SQLQueryObjectCore.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2024 Link.it srl (https://link.it).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openspcoop2.utils.sql;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.openspcoop2.utils.TipiDatabase;
/**
* Classe dove vengono forniti utility per la conversione di comandi SQL per database diversi
*
*
* @author Poli Andrea (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public abstract class SQLQueryObjectCore implements ISQLQueryObject{
private static final String LA_COLONNA_PREFIX = "La colonna ";
private static final String TABELLA_PREFIX = "Tabella ";
private static final String WHERE_CONDITION_PREFIX = "Where Condition ";
private static final String FIELD_NAME_PREFIX = "Field name ";
private static final String ALIAS_TABELLA_INDICATO_NON_ESISTE = "L'alias indicato non corrisponde ad un alias effettivo associato ad una tabella";
private static final String NESSUN_FIELD_IMPOSTATO = "Nessun field impostato";
private static final String GIA_ESISTENTE_TRA_CONDIZIONI_WHERE = " gia' esistente tra le condizioni di where";
private static final String FIELD_NAME_IS_NULL_OR_EMPTY = "Field name is null or empty string";
protected static final String CONDIZIONI_ORDER_BY_RICHESTE = "Condizioni di OrderBy richieste";
protected static final String TABELLA_RICERCA_FROM_NON_DEFINITA = "Tabella di ricerca (... FROM Table ...) non definita";
private static final String NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL = "nomeTabella non puo' essere null";
protected static final String FIELD_DEVE_ESSERE_DIVERSO_NULL = "field non puo' essere null";
private static final String IS_NULL_CONDITION_DEVE_ESSERE_DIVERSO_NULL = "IsNullCondition field non puo' essere null";
private static final String LOWER_PREFIX = "( lower(";
private static final String ESCAPE_SEPARATOR = " ESCAPE ";
private static final String LIKE_SEPARATOR = " LIKE ";
protected static final String FROM_SEPARATOR = " FROM ";
protected static final String FROM_SEPARATOR_APERTURA = " FROM ( ";
protected static final String WHERE_SEPARATOR = " WHERE ";
protected static final String AND_SEPARATOR = " AND ";
protected static final String OR_SEPARATOR = " OR ";
protected static final String ASC_SEPARATOR = " ASC ";
protected static final String DESC_SEPARATOR = " DESC ";
protected static final String GROUP_BY_SEPARATOR = " GROUP BY ";
protected static final String ORDER_BY_SEPARATOR = " ORDER BY ";
protected static final String LIMIT_SEPARATOR = " LIMIT ";
protected static final String NOT_SEPARATOR_APERTURA = " NOT ( ";
protected static final String SELECT_SEPARATOR_CON_INIZIO_APERTURA = " ( SELECT ";
protected static final String AS_SUBQUERY_SUFFIX = " ) as subquery";
private static SecureRandom rndEngine = null;
private static synchronized void initRandom() {
if(rndEngine==null) {
rndEngine = new SecureRandom();
}
}
protected static java.util.Random getRandom() {
if(rndEngine==null) {
initRandom();
}
return rndEngine;
}
/** List di Field esistenti: i nomi dei fields impostati (se e' stato utilizzato un alias ritorna comunque il nome della colonna) */
List<String> fields = new ArrayList<>();
/** List di NomiField esistenti: i nomi dei fields impostati (se e' stato utilizzato un alias ritorna il valore dell'alias) */
List<String> fieldNames = new ArrayList<>();
/** 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) */
Map<String, Boolean> fieldNameIsFunction = new HashMap<>();
/** Mapping tra alias (key) e field names (value) (sono presenti i mapping solo per le colonne per cui e' stato definito un alias) */
Map<String, String> alias = new HashMap<>();
/** List di Tabelle esistenti */
List<String> tables = new ArrayList<>();
List<String> tableNames = new ArrayList<>();
List<String> tableAlias = new ArrayList<>();
/** List di Field esistenti */
List<String> conditions = new ArrayList<>();
public int sizeConditions(){
return this.conditions.size();
}
/** List di indici forzati */
List<String> forceIndexTableNames = new ArrayList<>();
/** OperatorLogic */
boolean andLogicOperator = false;
/** Not */
boolean notBeforeConditions = false;
/** GroupBy di Field esistenti */
private List<String> groupBy = new ArrayList<>();
/** OrderBy di Field esistenti */
List<String> orderBy = new ArrayList<>();
Map<String, Boolean> orderBySortType = new HashMap<>();
/** Tipo di ordinamento */
boolean sortTypeAsc = true;
/** Distinct */
private boolean distinct = false;
/** Limit */
int limit = -1;
/** Offset */
int offset = -1;
/** SelectForUpdate */
boolean selectForUpdate = false;
/* UPDATE */
/** List di Field per l'update */
List<String> updateFieldsName = new ArrayList<>();
List<String> updateFieldsValue = new ArrayList<>();
/** Tabella per l'update */
String updateTable = null;
/* INSERT */
/** List di Field per l'insert */
List<String> insertFieldsName = new ArrayList<>();
List<String> insertFieldsValue = new ArrayList<>();
/** Tabella per l'insert */
String insertTable = null;
/* TipoDatabase */
private TipiDatabase tipoDatabase;
/* preCheck */
private boolean precheckQuery = true;
public void setPrecheckQuery(boolean precheckQuery) {
this.precheckQuery = precheckQuery;
}
// Increment
private int serial = 0;
protected synchronized int getSerial(){
this.serial++;
return this.serial;
}
// Force to false SelectForUpdate in CRUD Method
private boolean forceSelectForUpdateDisabledForNotQueryMethod = false; // viene usato nel progetto generic forzato a true per JDBC_SQLObjectFactory
public void setForceSelectForUpdateDisabledForNotQueryMethod(boolean forceSelectForUpdateDisabledForNotQueryMethod) {
this.forceSelectForUpdateDisabledForNotQueryMethod = forceSelectForUpdateDisabledForNotQueryMethod;
}
// COSTRUTTORE
protected SQLQueryObjectCore(TipiDatabase tipoDatabase){
this.tipoDatabase = tipoDatabase;
}
// UTILITIES
protected void precheckBuildQuery() throws SQLQueryObjectException{
if(!this.precheckQuery){
return;
}
// Check Offset
if(this.offset>=0 &&
this.orderBy.isEmpty()){
throw new SQLQueryObjectException("Condizioni di OrderBy richieste");
}
// Check GroupBy
precheckBuildQueryGroupBy();
// Check Select For Update
if(this.selectForUpdate){
if(this.groupBy!=null && !this.groupBy.isEmpty()){
throw new SQLQueryObjectException("Non è possibile abilitare il comando 'selectForUpdate' se viene utilizzata la condizione di GROUP BY");
}
else if(this.distinct){
throw new SQLQueryObjectException("Non è possibile abilitare il comando 'selectForUpdate' se viene utilizzata la clausola DISTINCT");
}
else if(this.limit>=0){
throw new SQLQueryObjectException("Non è possibile abilitare il comando 'selectForUpdate' se viene utilizzata la clausola LIMIT");
}
else if(this.offset>=0){
throw new SQLQueryObjectException("Non è possibile abilitare il comando 'selectForUpdate' se viene utilizzata la clausola OFFSET");
}
}
}
private void precheckBuildQueryGroupBy() throws SQLQueryObjectException{
if(this.groupBy!=null && !this.groupBy.isEmpty()){
// verifico che tutte le condizioni di order by siano presente anche nei field di group by
precheckBuildQueryGroupByOrderBy();
// verifico che tutte le condizioni di group by siano presenti anche nei field
for (String groupByCheck : this.groupBy) {
boolean exists = false;
for (String field : this.fields) {
if(normalizeField(groupByCheck).equals(normalizeField(field))){
exists = true;
break;
}
}
if(!exists){
throw new SQLQueryObjectException(LA_COLONNA_PREFIX+groupByCheck+" utilizzata nella condizione di GROUP BY deve essere anche selezionato come select field");
}
}
}
}
private void precheckBuildQueryGroupByOrderBy() throws SQLQueryObjectException{
if(!this.orderBy.isEmpty()){
for (String order : this.orderBy) {
precheckBuildQueryGroupByOrderBy(order);
}
}
}
private void precheckBuildQueryGroupByOrderBy(String order) throws SQLQueryObjectException{
boolean exists = false;
for (String groupByCheck : this.groupBy) {
if(normalizeField(groupByCheck).equals(normalizeField(order))){
exists = true;
break;
}
}
if(!exists){
String orderField = normalizeField(order);
try{
if(this.isFieldNameForFunction(orderField)==null || (!this.isFieldNameForFunction(orderField).booleanValue())){
throw new SQLQueryObjectException(LA_COLONNA_PREFIX+order+" utilizzata nella condizione di ORDER BY deve apparire anche in una condizione di GROUP BY");
}
}catch(SQLQueryObjectException sqlObject){
throw new SQLQueryObjectException(LA_COLONNA_PREFIX+order+" utilizzata nella condizione di ORDER BY deve apparire anche in una condizione di GROUP BY",sqlObject);
}
}
}
protected String normalizeField(String field){
return this.normalizeField(field, true);
}
protected String normalizeField(String field, boolean firstSearchFromAliasesField){
if(firstSearchFromAliasesField){
// 1. Viene fornito il nome della colonna su database.
// Potrebbe essere stato mappato con un alias nella select field.
// In tal caso deve essere ricavato ed utilizzato l'alias
Iterator<String> itRicercaAlias = this.fields.iterator();
while(itRicercaAlias.hasNext()){
String fieldRicercaAliasa = itRicercaAlias.next();
String [] split = null;
if(fieldRicercaAliasa.contains(" as ")){
split = fieldRicercaAliasa.split(" as ");
}else if(fieldRicercaAliasa.contains(" As ")){
split = fieldRicercaAliasa.split(" As ");
}else if(fieldRicercaAliasa.contains(" aS ")){
split = fieldRicercaAliasa.split(" aS ");
}else if(fieldRicercaAliasa.contains(" AS ")){
split = fieldRicercaAliasa.split(" AS ");
}else if(fieldRicercaAliasa.contains(" ")){
split = fieldRicercaAliasa.split(" ");
}else if(fieldRicercaAliasa.contains(this.getDefaultAliasFieldKeyword())){
split = fieldRicercaAliasa.split(this.getDefaultAliasFieldKeyword());
}
if(split==null){
List<String> aliases = this.getSupportedAliasesField();
if(aliases!=null && !aliases.isEmpty()){
for (String aliasCheck : aliases) {
if(fieldRicercaAliasa.contains(aliasCheck)){
split = fieldRicercaAliasa.split(aliasCheck);
break;
}
}
}
}
if(split!=null && split.length==2){
split[0] = split[0].trim();
split[1] = split[1].trim();
if(field.equals(split[0])){
return split[1];
}
}
}
}
// Alcuni valori sono standard dei vendor dei database (es. gestione delle date)
// Il problema è che se contengono dei '.' o dei caratteri alias rientrano erroneamnete nei punti 2 e 3 dove invece non dovrebbero rientraci.
// Per questo motivo viene quindi prima richiesto al vendor se effettuare o meno la classica normalizzazione del field in base a tali valori
// sul field in essere
if(!this.continueNormalizeField(field)){
return field;
}
// 2. Altrimenti devo verificare se vi e' un prefisso di tabella davanti
// Devono essere eliminati le TABELLE. e lasciare solo il field
int indexOf = field.indexOf(".");
if( (indexOf!=-1) && ((indexOf+1)<field.length()) ){
field = field.substring(indexOf+1);
}
// 3. Anche se ho eliminato il prefisso della tabella, potrei avere come field una stringa tipo 'colonna as alias'
// In tal caso devo tornare solo alias.
List<String> aliasModeSupportati = new ArrayList<>();
for (Iterator<?> iterator = this.getSupportedAliasesField().iterator(); iterator.hasNext();) {
aliasModeSupportati.add((String)iterator.next());
}
if(!aliasModeSupportati.contains(" ")){
aliasModeSupportati.add(" ");
}
if(!aliasModeSupportati.contains(" as ")){
aliasModeSupportati.add(" as ");
}
// itero su tutti gli alias (lastIndexOf utile per i casi di min/max/avg/sum timestamp field dove vengono usato anche altri alias internamente)
for (Iterator<?> iterator = aliasModeSupportati.iterator(); iterator.hasNext();) {
String aliasCheck = (String) iterator.next();
int aliasLength = aliasCheck.length(); //4
// Inoltre se vi sono alias, devono essere eliminati i field davanti agli alias e lasciati solo gli alias:
// Es. SCORRETTO : SELECT id as IDAlias from (select id as IDAlias...)
// Es. CORRETTO : SELECT IDAlias from (select id as IDAlias...)
String fLowerCase = field.toLowerCase();
/**indexOf = fLowerCase.lastIndexOf(" as ");*/
indexOf = fLowerCase.lastIndexOf(aliasCheck);
if( (indexOf!=-1) && ((indexOf+aliasLength)<field.length()) ){
field = field.substring(indexOf+aliasLength);
field = field.trim();
break;
}
}
return field;
}
protected boolean continueNormalizeField(String normalizeField){
// Alcuni valori sono standard dei vendor dei database (es. gestione delle date)
// Il problema è che se contengono dei '.' o dei caratteri alias rientrano erroneamnete nei punti 2 e 3 della normalizzazione
// Per questo motivo viene quindi prima richiesto al vendor se effettuare o meno la classica normalizzazione del field in base a tali valori
// sul field in essere
// Vedere quali database sovrascrivono questo metodo
// Ad esempio SQLServer
if(normalizeField!=null) {
// nop
}
return true;
}
protected String getCaseCondition(Case caseValue) throws SQLQueryObjectException {
if(caseValue==null) {
throw new SQLQueryObjectException("Field caseValue is null");
}
if(caseValue.getValori()==null || caseValue.getValori().isEmpty() ||
caseValue.getCondizioni()==null || caseValue.getCondizioni().isEmpty()) {
throw new SQLQueryObjectException("Field caseValue non contiene condizioni");
}
if(caseValue.getValori().size()!=caseValue.getCondizioni().size()) {
throw new SQLQueryObjectException("Field caseValue contiene condizioni con un numero di valori differenti dalle condizioni di where?");
}
if(caseValue.getTipoColonna()==null) {
throw new SQLQueryObjectException("Field caseValue non contiene il tipo della colonna");
}
StringBuilder bf = new StringBuilder();
bf.append("CASE");
for (int i = 0; i < caseValue.getValori().size(); i++) {
String valore = caseValue.getValori().get(i);
String condizione = caseValue.getCondizioni().get(i);
bf.append(" WHEN ").append(condizione);
bf.append(" THEN ");
bf.append(getPrefixCastValue(caseValue.getTipoColonna(),caseValue.getDimensioneColonna()));
if(caseValue.isStringValueType()){
bf.append("'");
bf.append(escapeStringValue(valore));
bf.append("'");
}
else{
bf.append(valore);
}
bf.append(getSuffixCastValue(caseValue.getTipoColonna(),caseValue.getDimensioneColonna()));
}
if(caseValue.getValoreDefault()!=null) {
bf.append(" ELSE ");
bf.append(getPrefixCastValue(caseValue.getTipoColonna(),caseValue.getDimensioneColonna()));
if(caseValue.isStringValueType()){
bf.append("'");
bf.append(escapeStringValue(caseValue.getValoreDefault()));
bf.append("'");
}
else{
bf.append(caseValue.getValoreDefault());
}
bf.append(getSuffixCastValue(caseValue.getTipoColonna(),caseValue.getDimensioneColonna()));
}
bf.append(" END");
return bf.toString();
}
// SELECT FIELDS NORMALI
/**
* Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
* es: SELECT nomeField FROM ....
*
* @param nomeField Nome del Field
*/
@Override
public ISQLQueryObject addSelectField(String nomeField) throws SQLQueryObjectException{
return this.addSelectField(null,nomeField);
}
/**
* Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
* es: SELECT nomeTabella.nomeField FROM ....
*
* @param nomeTabella Nome della tabella su cui reperire il field
* @param nomeField Nome del Field
*/
@Override
public ISQLQueryObject addSelectField(String nomeTabella,String nomeField) throws SQLQueryObjectException{
return this.engineAddSelectField(nomeTabella,nomeField,null,true,false);
}
/**
* Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
* es: SELECT nomeField FROM ....
*
* @param nomeField Nome del Field
*/
@Override
public ISQLQueryObject addSelectAliasField(String nomeField,String alias) throws SQLQueryObjectException{
return this.engineAddSelectField(null,nomeField,alias,true,false);
}
/**
* Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
* es: SELECT nomeTabella.nomeField FROM ....
*
* @param nomeTabella Nome della tabella su cui reperire il field
* @param nomeField Nome del Field
*/
@Override
public ISQLQueryObject addSelectAliasField(String nomeTabella,String nomeField,String alias) throws SQLQueryObjectException{
return this.engineAddSelectField(nomeTabella,nomeField,alias,true,false);
}
// SELECT FIELDS COALESCE
/**
* Aggiunge un field alla select definendolo tramite la funzione coalesce
* es: SELECT coalesce(nomeField, 'VALORE') as alias FROM ....
*
* @param nomeField Nome del Field
* @param alias Alias
* @param valore Valore utilizzato in caso il campo sia null
*/
@Override
public ISQLQueryObject addSelectCoalesceField(String nomeField,String alias,String valore) throws SQLQueryObjectException{
return engineAddSelectField(null, nomeField, alias, true, "coalesce(",",'"+escapeStringValue(valore)+"')",true);
}
/**
* Aggiunge un field alla select definendolo tramite la funzione coalesce
* es: SELECT coalesce(nomeTabella.nomeField, 'VALORE') as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param nomeField Nome del Field
* @param alias Alias
* @param valore Valore utilizzato in caso il campo sia null
*/
@Override
public ISQLQueryObject addSelectCoalesceField(String aliasTabella,String nomeField,String alias,String valore) throws SQLQueryObjectException{
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
return engineAddSelectField(aliasTabella, nomeField, alias, true, "coalesce(",",'"+escapeStringValue(valore)+"')",true);
}
// SELECT FIELDS CASE
/**
* Aggiunge un field alla select definendolo tramite la funzione coalesce
* es: SELECT coalesce(nomeField, 'VALORE') as alias FROM ....
*
* @param caseField Case
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectCaseField(Case caseField, String alias) throws SQLQueryObjectException{
if(alias==null || "".equals(alias))
throw new SQLQueryObjectException("Alias is null or empty string");
String caseValue = this.getCaseCondition(caseField);
String field = "("+caseValue+")"+this.getDefaultAliasFieldKeyword()+alias;
this.fields.add(field);
this.fieldNames.add(alias);
this.fieldNameIsFunction.put(alias, false);
return this;
}
// SELECT FIELDS COUNTS
/**
* Aggiunge un field count alla select, con un alias, del campo <var>fieldCount</var>
* es: SELECT count(*) as alias FROM ....
*
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectCountField(String alias) throws SQLQueryObjectException{
String fieldSQL = "count(*)";
if(alias != null){
/**fieldSQL = fieldSQL + " as "+alias;*/
fieldSQL = fieldSQL + getDefaultAliasFieldKeyword() + alias;
}
this.engineAddSelectField(null,fieldSQL,null,false,true);
this.fieldNames.add(alias);
this.fieldNameIsFunction.put(alias, true);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>fieldCount</var>
* es: SELECT count(fieldCount) as alias FROM ....
*
* @param fieldCount Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectCountField(String fieldCount,String alias) throws SQLQueryObjectException{
if(fieldCount==null)
fieldCount = "*";
String fieldSQL = "count("+fieldCount+")";
if(alias != null){
/**fieldSQL = fieldSQL + " as "+alias;*/
fieldSQL = fieldSQL + getDefaultAliasFieldKeyword() + alias;
}
this.engineAddSelectField(null,fieldSQL,null,false,true);
this.fieldNames.add(alias);
this.fieldNameIsFunction.put(alias, true);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>fieldCount</var>
* es: SELECT count(DISTINCT fieldCount) as alias FROM ....
*
* @param fieldCount Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectCountField(String fieldCount,String alias,boolean distinct) throws SQLQueryObjectException{
if(fieldCount==null && distinct)
throw new SQLQueryObjectException("Non e' possibile utilizzare DISTINCT senza specificare un fieldCount");
if(distinct)
addSelectCountField("DISTINCT "+fieldCount,alias);
else
addSelectCountField(fieldCount,alias);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>fieldCount</var>
* es: SELECT count(nomeTabella.fieldCount) as alias FROM ....
*
* @param aliasTabella Nome della tabella su cui reperire il field
* @param fieldCount Alias del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectCountField(String aliasTabella,String fieldCount,String alias) throws SQLQueryObjectException{
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
this.addSelectCountField(aliasTabella+"."+fieldCount, alias);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>fieldCount</var>
* es: SELECT count(DISTINCT nomeTabella.fieldCount) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param fieldCount Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectCountField(String aliasTabella,String fieldCount,String alias,boolean distinct) throws SQLQueryObjectException{
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
this.addSelectCountField(aliasTabella+"."+fieldCount, alias, distinct);
return this;
}
// SELECT FIELDS AVG
/**
* Aggiunge un field count alla select, con un alias, del campo <var>fieldAvg</var>
* es: SELECT count(fieldAvg) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectAvgField(String field,String alias) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException("field avg non puo' essere null");
engineAddSelectField(null, field, alias, true, "avg(",")",true);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>fieldAvg</var>
* es: SELECT avg(nomeTabella.fieldAvg) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectAvgField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException("field avg non puo' essere null");
if(aliasTabella==null)
throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
engineAddSelectField(aliasTabella, field, alias, true, "avg(",")",true);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>fieldAvg</var> (di tipo Timestamp)
* es: SELECT avg(fieldAvg) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
/**@Override
public abstract ISQLQueryObject addSelectAvgTimestampField(String field,String alias) throws SQLQueryObjectException;*/
/**
* Aggiunge un field count alla select, con un alias, del campo <var>fieldAvg</var> (di tipo Timestamp)
* es: SELECT avg(nomeTabella.fieldAvg) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectAvgTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
addSelectAvgTimestampField(aliasTabella+"."+field, alias);
return this;
}
// SELECT FIELDS MAX
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var>
* es: SELECT max(field) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectMaxField(String field,String alias) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
engineAddSelectField(null, field, alias, true, "max(",")",true);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var>
* es: SELECT max(nomeTabella.field) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias alias
*/
@Override
public ISQLQueryObject addSelectMaxField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
if(aliasTabella==null)
throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
engineAddSelectField(aliasTabella, field, alias, true, "max(",")",true);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
* es: SELECT max(field) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
/**@Override
public abstract ISQLQueryObject addSelectMaxTimestampField(String field,String alias) throws SQLQueryObjectException;*/
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
* es: SELECT max(nomeTabella.field) as alias FROM ....
*
* @param aliasTabella alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectMaxTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
addSelectMaxTimestampField(aliasTabella+"."+field, alias);
return this;
}
// SELECT FIELDS MIN
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var>
* es: SELECT min(field) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectMinField(String field,String alias) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
engineAddSelectField(null, field, alias, true, "min(",")",true);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var>
* es: SELECT min(nomeTabella.field) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias
*/
@Override
public ISQLQueryObject addSelectMinField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
if(aliasTabella==null)
throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
engineAddSelectField(aliasTabella, field, alias, true, "min(",")",true);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
* es: SELECT min(field) as alias FROM ....
*
* @param field Nome del Field
* @param alias
*/
/**@Override
public abstract ISQLQueryObject addSelectMinTimestampField(String field,String alias) throws SQLQueryObjectException;*/
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
* es: SELECT min(nomeTabella.field) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias
*/
@Override
public ISQLQueryObject addSelectMinTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
addSelectMinTimestampField(aliasTabella+"."+field, alias);
return this;
}
// SELECT FIELDS SUM
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var>
* es: SELECT sum(field) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectSumField(String field,String alias) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
engineAddSelectField(null, field, alias, true, "sum(",")",true);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var>
* es: SELECT sum(nomeTabella.field) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias
*/
@Override
public ISQLQueryObject addSelectSumField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
if(aliasTabella==null)
throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
engineAddSelectField(aliasTabella, field, alias, true, "sum(",")",true);
return this;
}
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
* es: SELECT sum(field) as alias FROM ....
*
* @param field Nome del Field
* @param alias
*/
/**@Override
public abstract ISQLQueryObject addSelectSumTimestampField(String field,String alias) throws SQLQueryObjectException;*/
/**
* Aggiunge un field count alla select, con un alias, del campo <var>field</var> (di tipo Timestamp)
* es: SELECT sum(nomeTabella.field) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias
*/
@Override
public ISQLQueryObject addSelectSumTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
addSelectSumTimestampField(aliasTabella+"."+field, alias);
return this;
}
// DATE TIME
protected static final String DATE_PART_YEAR = "YEAR";
protected static final String DATE_PART_MONTH = "MONTH";
protected static final String DATE_PART_DAY = "DAY";
protected static final String TIME_PART_HOUR = "HOUR";
protected static final String TIME_PART_MINUTE = "MINUTE";
protected static final String TIME_PART_SECOND = "SECOND";
protected String getDateTimePart(DateTimePartEnum dateTimePart) throws SQLQueryObjectException {
switch (dateTimePart) {
case YEAR:
return DATE_PART_YEAR;
case MONTH:
return DATE_PART_MONTH;
case DAY:
return DATE_PART_DAY;
case HOUR:
return TIME_PART_HOUR;
case MINUTE:
return TIME_PART_MINUTE;
case SECOND:
return TIME_PART_SECOND;
}
throw new SQLQueryObjectException("DateTimePartEnum '"+dateTimePart+"' unknown");
}
public String getExtractDateTimePartFromTimestampFieldPrefix(DateTimePartEnum dateTimePart) throws SQLQueryObjectException {
if(dateTimePart==null) {
throw new SQLQueryObjectException("dateTimePart undefined");
}
String dateTimePartString = getDateTimePart(dateTimePart);
return "EXTRACT("+dateTimePartString+FROM_SEPARATOR;
}
public String getExtractDateTimePartFromTimestampFieldSuffix(DateTimePartEnum dateTimePart) throws SQLQueryObjectException {
if(dateTimePart==null) {
throw new SQLQueryObjectException("dateTimePart undefined");
}
return ")";
}
private ISQLQueryObject addSelectTimestampFieldEngine(String field,String alias, DateTimePartEnum dateTimePart) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
engineAddSelectField(null, field, alias, true,
getExtractDateTimePartFromTimestampFieldPrefix(dateTimePart),
getExtractDateTimePartFromTimestampFieldSuffix(dateTimePart),
true);
return this;
}
private ISQLQueryObject addSelectTimestampFieldEngine(String aliasTabella,String field,String alias, DateTimePartEnum dateTimePart) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
if(aliasTabella==null)
throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
engineAddSelectField(aliasTabella, field, alias, true,
getExtractDateTimePartFromTimestampFieldPrefix(dateTimePart),
getExtractDateTimePartFromTimestampFieldSuffix(dateTimePart),
true);
return this;
}
/**
* Aggiunge un field alla select che si occupa di estrarre l'anno dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(YEAR FROM field) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectYearTimestampField(String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.YEAR);
}
/**
* Aggiunge un field alla select che si occupa di estrarre l'anno dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(YEAR FROM nomeTabella.field) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectYearTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.YEAR);
}
/**
* Aggiunge un field alla select che si occupa di estrarre il mese dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(MONTH FROM field) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectMonthTimestampField(String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.MONTH);
}
/**
* Aggiunge un field alla select che si occupa di estrarre il mese dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(MONTH FROM nomeTabella.field) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectMonthTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.MONTH);
}
/**
* Aggiunge un field alla select che si occupa di estrarre il giorno dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(DAY FROM field) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectDayTimestampField(String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.DAY);
}
/**
* Aggiunge un field alla select che si occupa di estrarre il giorno dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(DAY FROM nomeTabella.field) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectDayTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.DAY);
}
/**
* Aggiunge un field alla select che si occupa di estrarre l'ora dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(HOUR FROM field) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectHourTimestampField(String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.HOUR);
}
/**
* Aggiunge un field alla select che si occupa di estrarre l'ora dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(HOUR FROM nomeTabella.field) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectHourTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.HOUR);
}
/**
* Aggiunge un field alla select che si occupa di estrarre i minuti dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(MINUTE FROM field) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectMinuteTimestampField(String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.MINUTE);
}
/**
* Aggiunge un field alla select che si occupa di estrarre i minuti dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(MINUTE FROM nomeTabella.field) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectMinuteTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.MINUTE);
}
/**
* Aggiunge un field alla select che si occupa di estrarre i secondi dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(SECOND FROM field) as alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectSecondTimestampField(String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(field, alias, DateTimePartEnum.SECOND);
}
/**
* Aggiunge un field alla select che si occupa di estrarre i secondi dal campo <var>field</var> (di tipo Timestamp)
* es: SELECT EXTRACT(SECOND FROM nomeTabella.field) as alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectSecondTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(aliasTabella, field, alias, DateTimePartEnum.SECOND);
}
private static final String DAY_FORMAT_FULL_DAY_NAME = "DAY";
private static final String DAY_FORMAT_SHORT_DAY_NAME = "DY";
private static final String DAY_FORMAT_DAY_OF_YEAR = "DDD";
private static final String DAY_FORMAT_DAY_OF_WEEK = "D";
protected String getDayFormat(DayFormatEnum dayFormat) throws SQLQueryObjectException {
switch (dayFormat) {
case FULL_DAY_NAME:
return DAY_FORMAT_FULL_DAY_NAME;
case SHORT_DAY_NAME:
return DAY_FORMAT_SHORT_DAY_NAME;
case DAY_OF_YEAR:
return DAY_FORMAT_DAY_OF_YEAR;
case DAY_OF_WEEK:
return DAY_FORMAT_DAY_OF_WEEK;
}
throw new SQLQueryObjectException("DayFormatEnum '"+dayFormat+"' unknown");
}
public String getExtractDayFormatFromTimestampFieldPrefix(DayFormatEnum dayFormat) throws SQLQueryObjectException {
if(dayFormat==null) {
throw new SQLQueryObjectException("dayFormat undefined");
}
return "TO_CHAR(";
}
public String getExtractDayFormatFromTimestampFieldSuffix(DayFormatEnum dayFormat) throws SQLQueryObjectException {
if(dayFormat==null) {
throw new SQLQueryObjectException("dayFormat undefined");
}
String dayFormatString = getDayFormat(dayFormat);
return ", '"+dayFormatString+"')";
}
private ISQLQueryObject addSelectTimestampFieldEngine(String field,String alias, DayFormatEnum dayFormatEnum) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
engineAddSelectField(null, field, alias, true,
getExtractDayFormatFromTimestampFieldPrefix(dayFormatEnum),
getExtractDayFormatFromTimestampFieldSuffix(dayFormatEnum),
true);
return this;
}
private ISQLQueryObject addSelectTimestampFieldEngine(String aliasTabella,String field,String alias, DayFormatEnum dayFormatEnum) throws SQLQueryObjectException{
if(field==null)
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
if(aliasTabella==null)
throw new SQLQueryObjectException(NOME_TABELLA_DEVE_ESSERE_DIVERSO_NULL);
if(!this.tableAlias.contains(aliasTabella)){
throw new SQLQueryObjectException(ALIAS_TABELLA_INDICATO_NON_ESISTE);
}
engineAddSelectField(aliasTabella, field, alias, true,
getExtractDayFormatFromTimestampFieldPrefix(dayFormatEnum),
getExtractDayFormatFromTimestampFieldSuffix(dayFormatEnum),
true);
return this;
}
/**
* 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'
* es: TO_CHAR(field, 'DAY') AS alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectFullDayNameTimestampField(String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(field, alias, DayFormatEnum.FULL_DAY_NAME);
}
/**
* 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'
* es: TO_CHAR(nomeTabella.field, 'DAY') AS alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectFullDayNameTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(aliasTabella, field, alias, DayFormatEnum.FULL_DAY_NAME);
}
/**
* 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'
* es: TO_CHAR(field, 'DY') AS alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectShortDayNameTimestampField(String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(field, alias, DayFormatEnum.SHORT_DAY_NAME);
}
/**
* 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'
* es: TO_CHAR(nomeTabella.field, 'DY') AS alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectShortDayNameTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(aliasTabella, field, alias, DayFormatEnum.SHORT_DAY_NAME);
}
/**
* 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'
* es: TO_CHAR(field, 'DDD') AS alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectDayOfYearTimestampField(String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(field, alias, DayFormatEnum.DAY_OF_YEAR);
}
/**
* 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'
* es: TO_CHAR(nomeTabella.field, 'DDD') AS alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectDayOfYearTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(aliasTabella, field, alias, DayFormatEnum.DAY_OF_YEAR);
}
/**
* 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'
* es: TO_CHAR(field, 'D') AS alias FROM ....
*
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectDayOfWeekTimestampField(String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(field, alias, DayFormatEnum.DAY_OF_WEEK);
}
/**
* 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'
* es: TO_CHAR(nomeTabella.field, 'D') AS alias FROM ....
*
* @param aliasTabella Alias della tabella su cui reperire il field
* @param field Nome del Field
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectDayOfWeekTimestampField(String aliasTabella,String field,String alias) throws SQLQueryObjectException{
return addSelectTimestampFieldEngine(aliasTabella, field, alias, DayFormatEnum.DAY_OF_WEEK);
}
/**
* Aggiunge una costante alla select di tipo 'timestamp'
* es: timestamp 'costante' AS alias FROM ....
*
* @param date Costante
* @param alias Alias
*/
@Override
public ISQLQueryObject addSelectTimestampConstantField(Date date,String alias) throws SQLQueryObjectException{
if(date==null)
throw new SQLQueryObjectException("Date non puo' essere null");
String constantValue = getSelectTimestampConstantField(date);
return this.addSelectAliasField(constantValue, alias);
}
// SELECT FORCE INDEX
/**
* Aggiunge l'istruzione SQL per forzare l'utilizzo dell'indice indicato nel parametro nella lettura della tabella indicata
* es: SELECT '/*+ index(nomeTabella indexName) *' FROM ....
*
* @param nomeTabella Nome della tabella su cui forzare l'indice
* @param indexName Nome dell'indice
*/
@Override
public ISQLQueryObject addSelectForceIndex(String nomeTabella,String indexName) throws SQLQueryObjectException{
// per adesso implementato solamente per oracle
return this;
}
// SET DISTINCTS IN CIMA ALLA SELECT
/**
* Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
* es: SELECT DISTINCT nomeField,nomeFiled2.... FROM ....
*
* @param value Indicazione sul distinct
*/
@Override
public void setSelectDistinct(boolean value) throws SQLQueryObjectException{
this.distinct = value;
}
public boolean isSelectDistinct() throws SQLQueryObjectException{
if(this.distinct &&
this.fields.isEmpty()){
throw new SQLQueryObjectException("Per usare la select distinct devono essere indicati dei select field");
}
return this.distinct;
}
// FIELDS/TABLE NAME
/**
* Ritorna i nomi dei fields impostati (se e' stato utilizzato un alias ritorna il valore dell'alias)
*
* @return i nomi dei fields impostati (se e' stato utilizzato un alias ritorna il valore dell'alias)
* @throws SQLQueryObjectException
*/
@Override
public List<String> getFieldsName() throws SQLQueryObjectException{
if(this.fieldNames==null || this.fieldNames.isEmpty()){
throw new SQLQueryObjectException(NESSUN_FIELD_IMPOSTATO);
}
return this.fieldNames;
}
/**
* Indicazione se e' il nome rappresenta una funzione
*
* @return Indicazione se e' il nome rappresenta una funzione
* @throws SQLQueryObjectException
*/
@Override
public Boolean isFieldNameForFunction(String fieldName) throws SQLQueryObjectException{
if(this.fieldNames==null || this.fieldNames.isEmpty()){
throw new SQLQueryObjectException(NESSUN_FIELD_IMPOSTATO);
}
if(!this.fieldNameIsFunction.containsKey(fieldName)){
throw new SQLQueryObjectException("Field ["+fieldName+"] non presente (se durante la definizione del field e' stato usato un 'alias' utilizzarlo come parametro di questo metodo)");
}
return this.fieldNameIsFunction.get(fieldName);
}
/**
* Ritorna i nomi dei fields impostati (se e' stato utilizzato un alias ritorna comunque il nome della colonna)
*
* @return nomi dei fields impostati (se e' stato utilizzato un alias ritorna comunque il nome della colonna)
* @throws SQLQueryObjectException
*/
//@Override
public List<String> getFields() throws SQLQueryObjectException{
if(this.fields==null || this.fields.isEmpty()){
throw new SQLQueryObjectException(NESSUN_FIELD_IMPOSTATO);
}
return this.fields;
}
/**
* Ritorna i nomi delle tabelle impostate (se e' stato utilizzato un alias ritorna il valore dell'alias)
*
* @return nomi delle tabelle impostate (se e' stato utilizzato un alias ritorna il valore dell'alias)
* @throws SQLQueryObjectException
*/
@Override
public List<String> getTablesName() throws SQLQueryObjectException{
if(this.tableNames==null || this.tableNames.isEmpty()){
throw new SQLQueryObjectException("Nessuna tabella impostata");
}
return this.tableNames;
}
/**
* Ritorna i nomi delle tabelle impostate (se e' stato utilizzato un alias ritorna comunque il nome della tabella)
*
* @return nomi delle tabelle impostate (se e' stato utilizzato un alias ritorna comunque il nome della tabella)
* @throws SQLQueryObjectException
*/
//@Override
public List<String> getTables() throws SQLQueryObjectException{
if(this.tables==null || this.tables.isEmpty()){
throw new SQLQueryObjectException("Nessuna tabella impostata");
}
return this.tables;
}
/// FIELDS UNIX FUNCTIONS
/**
* Ritorna la conversione in UnixTimestamp della Colonna
*
* @param column colonna da convertire in UnixTimestamp
* @return conversione in UnixTimestamp della Colonna
*/
/**@Override
public abstract String getUnixTimestampConversion(String column);*/
/**
* Ritorna l'intervallo in unixTimestamp tra le due colonne fornite
*
* @param columnMax colonna con intervallo temporale maggiore
* @param columnMin colonna con intervallo temporale minore
* @return ritorna l'intervallo in unixTimestamp tra le due colonne fornite
*/
/**@Override
public abstract String getDiffUnixTimestamp(String columnMax,String columnMin);*/
// FIELDS/TABLE ALIAS
// GESTIONE ALIAS 'as'
// Non tutti i database supportano l'alias 'as', ad esempio Oracle genera un errore se viene usato l'alias con le tabelle.
/**
* Ritorna l'alias di default utilizzabile per un field
*
* @return Ritorna l'alias di default utilizzabile per un field
*/
@Override
public String getDefaultAliasFieldKeyword(){
return this.getSupportedAliasesField().get(0);
}
/**
* Ritorna l'alias di default utilizzabile per una tabella
*
* @return Ritorna l'alias di default utilizzabile per una tabella
*/
@Override
public String getDefaultAliasTableKeyword(){
return this.getSupportedAliasesTable().get(0);
}
/**
* Ritorna gli aliases utilizzabili per un field
*
* @return Ritorna gli aliases utilizzabili per un field
*/
@Override
public List<String> getSupportedAliasesField(){
return getSupportedAliasesEngine();
}
/**
* Ritorna gli aliases utilizzabili per una tabella
*
* @return Ritorna gli aliases utilizzabili per una tabella
*/
@Override
public List<String> getSupportedAliasesTable(){
return getSupportedAliasesEngine();
}
private List<String> getSupportedAliasesEngine(){
List<String> lista = new ArrayList<>();
lista.add(" as ");
lista.add(" ");
return lista;
}
// Engine
/**
* Aggiunge un field alla select, se non sono presenti field, viene utilizzato '*'
* es: SELECT nomeTabella.nomeField FROM ....
*
* @param nomeTabella Nome della tabella su cui reperire il field
* @param nomeField Nome del Field
*/
protected ISQLQueryObject engineAddSelectField(String nomeTabella,String nomeField,String alias,boolean addFieldName,boolean isFunction) throws SQLQueryObjectException{
return engineAddSelectField(nomeTabella, nomeField, alias, addFieldName, null, null,isFunction);
}
protected ISQLQueryObject engineAddSelectField(String nomeTabella,String nomeField,String alias,boolean addFieldName,
String functionPrefix,String functionSuffix,boolean isFunction) throws SQLQueryObjectException{
if(nomeField==null || "".equals(nomeField))
throw new SQLQueryObjectException("Field is null or empty string");
checkEngineAddSelectField(nomeField, alias);
if(nomeTabella!=null && (!"".equals(nomeTabella))){
engineAddSelectField(nomeTabella, nomeField, alias,
functionPrefix, functionSuffix);
}else{
engineAddSelectField(nomeField, alias,
functionPrefix, functionSuffix);
}
if(addFieldName){
if(alias!=null){
this.fieldNames.add(alias);
this.fieldNameIsFunction.put(alias, isFunction);
}else{
this.fieldNames.add(nomeField);
this.fieldNameIsFunction.put(nomeField, isFunction);
}
}
return this;
}
private void checkEngineAddSelectField(String nomeField,String alias) throws SQLQueryObjectException {
if(alias!=null){
if(this.fields.contains("*")){
throw new SQLQueryObjectException("Alias "+alias+" del field "+nomeField+" non utilizzabile tra i select fields. La presenza del select field '*' non permette di inserirne altri");
}
if(this.fieldNames.contains(alias))
throw new SQLQueryObjectAlreadyExistsException("Alias "+alias+" gia inserito tra i select fields");
}else{
if(!"*".equals(nomeField) &&
this.fields.contains("*")){
throw new SQLQueryObjectException("Field "+nomeField+" non utilizzabile tra i select fields. La presenza del select field '*' non permette di inserirne altri");
}
if(this.fields.contains(nomeField))
throw new SQLQueryObjectAlreadyExistsException("Field "+nomeField+" gia inserito tra i select fields");
}
}
private void engineAddSelectField(String nomeTabella, String nomeField, String alias,
String functionPrefix,String functionSuffix) throws SQLQueryObjectException {
if(!this.tableNames.contains(nomeTabella))
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)");
String nomeTabellaConField = nomeTabella+"."+nomeField;
if(functionPrefix!=null){
nomeTabellaConField = functionPrefix + nomeTabellaConField;
}
if(functionSuffix!=null){
nomeTabellaConField = nomeTabellaConField + functionSuffix ;
}
if(alias!=null){
/**this.fields.add(nomeTabellaConField+" as "+alias);*/
this.fields.add(nomeTabellaConField+this.getDefaultAliasFieldKeyword()+alias);
this.alias.put(alias, nomeTabellaConField);
}else{
this.fields.add(nomeTabellaConField);
}
}
private void engineAddSelectField(String nomeField, String alias,
String functionPrefix,String functionSuffix) {
String tmp = nomeField + "";
if(functionPrefix!=null){
tmp = functionPrefix + tmp;
}
if(functionSuffix!=null){
tmp = tmp + functionSuffix ;
}
if(alias!=null){
/**this.fields.add(tmp+" as "+alias);*/
this.fields.add(tmp+this.getDefaultAliasFieldKeyword()+alias);
this.alias.put(alias, tmp);
}else{
this.fields.add(tmp);
}
}
// FROM
/**
* Aggiunge una tabella di ricerca del from
* es: SELECT * from tabella as tabella
*
* @param tabella
*/
@Override
public ISQLQueryObject addFromTable(String tabella) throws SQLQueryObjectException{
if(tabella==null || "".equals(tabella))
throw new SQLQueryObjectException("Tabella is null or empty string");
if(this.tableNames.contains(tabella))
throw new SQLQueryObjectAlreadyExistsException(TABELLA_PREFIX+tabella+" gia' esistente tra le tabella su cui effettuare la ricerca");
this.tableNames.add(tabella);
this.tables.add(tabella);
return this;
}
/**
* Aggiunge una tabella di ricerca del from
* es: SELECT * from tabella as alias
*
* @param tabella Tabella
* @param alias Alias
*/
@Override
public ISQLQueryObject addFromTable(String tabella,String alias) throws SQLQueryObjectException{
if(tabella==null || "".equals(tabella))
throw new SQLQueryObjectException("Tabella is null or empty string");
if(alias==null || "".equals(alias))
throw new SQLQueryObjectException("Alias tabella is null or empty string");
if(this.tableNames.contains(alias))
throw new SQLQueryObjectAlreadyExistsException(TABELLA_PREFIX+tabella+" gia' esistente tra le tabella su cui effettuare la ricerca");
this.tableNames.add(alias);
/**this.tables.add(tabella+" as "+alias);*/
this.tables.add(tabella+this.getDefaultAliasTableKeyword()+alias);
this.tableAlias.add(alias);
return this;
}
// WHERE
/**
* Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
* es: SELECT * from tabella WHERE (condition)
*
* @param condition
*/
@Override
public ISQLQueryObject addWhereCondition(String condition) throws SQLQueryObjectException{
if(condition==null || "".equals(condition))
throw new SQLQueryObjectException("Where Condition is null or empty string");
String buildCondition = "( "+condition+" )";
if( (buildCondition.indexOf("?")==-1) && this.conditions.contains(buildCondition))
throw new SQLQueryObjectException(WHERE_CONDITION_PREFIX+condition+GIA_ESISTENTE_TRA_CONDIZIONI_WHERE);
this.conditions.add(buildCondition);
return this;
}
/**
* Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
* Imposta come operatore logico di una successiva condizione (se esiste) l'AND se true, l'OR se false
* es: SELECT * from tabella WHERE ((condition1) andLogicOperator (condition2) etc.....)
*
* @param andLogicOperator
* @param conditions
*/
@Override
public ISQLQueryObject addWhereCondition(boolean andLogicOperator,String... conditions) throws SQLQueryObjectException{
this.addWhereCondition(andLogicOperator, false, conditions);
return this;
}
/**
* Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
* Imposta come operatore logico di una successiva condizione (se esiste) l'AND se true, l'OR se false
* es: SELECT * from tabella WHERE ( [NOT] ( (condition1) andLogicOperator (condition2) etc.....) )
* Se il parametro not is true, aggiunge il not davanti alle condizioni
*
* @param andLogicOperator
* @param not
* @param conditions
*/
@Override
public ISQLQueryObject addWhereCondition(boolean andLogicOperator,boolean not,String... conditions) throws SQLQueryObjectException{
if(conditions==null || conditions.length<=0)
throw new SQLQueryObjectException("Where Conditions non esistenti");
StringBuilder buildCondition = new StringBuilder();
if(not){
buildCondition.append("( NOT ");
}
buildCondition.append("( ");
addWhereCondition(buildCondition, andLogicOperator, conditions);
buildCondition.append(" )");
if(not){
buildCondition.append(")");
}
if((buildCondition.indexOf("?")==-1) && this.conditions.contains(buildCondition.toString()))
throw new SQLQueryObjectException(WHERE_CONDITION_PREFIX+buildCondition.toString()+GIA_ESISTENTE_TRA_CONDIZIONI_WHERE);
this.conditions.add(buildCondition.toString());
return this;
}
private void addWhereCondition(StringBuilder buildCondition, boolean andLogicOperator,String... conditions) throws SQLQueryObjectException {
for(int i=0; i<conditions.length; i++){
if(i>0){
if(andLogicOperator){
buildCondition.append(AND_SEPARATOR);
}else{
buildCondition.append(OR_SEPARATOR);
}
}
if(conditions[i]==null || "".equals(conditions[i]))
throw new SQLQueryObjectException("Where Condition["+i+"] is null or empty string");
buildCondition.append("(");
buildCondition.append(conditions[i]);
buildCondition.append(")");
}
}
/**
* Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
* es: SELECT * from tabella WHERE (field is null)
*
* @param field Field da verificare
*/
@Override
public ISQLQueryObject addWhereIsNullCondition(String field) throws SQLQueryObjectException{
if(field==null || "".equals(field)){
throw new SQLQueryObjectException(IS_NULL_CONDITION_DEVE_ESSERE_DIVERSO_NULL);
}
this.addWhereCondition(field+" is null");
return this;
}
/**
* Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
* es: SELECT * from tabella WHERE (field is not null)
*
* @param field Field da verificare
*/
@Override
public ISQLQueryObject addWhereIsNotNullCondition(String field) throws SQLQueryObjectException{
if(field==null || "".equals(field)){
throw new SQLQueryObjectException(IS_NULL_CONDITION_DEVE_ESSERE_DIVERSO_NULL);
}
this.addWhereCondition(field+" is not null");
return this;
}
/**
* Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
* es: SELECT * from tabella WHERE (field = '')
*
* @param field Field da verificare
*/
@Override
public ISQLQueryObject addWhereIsEmptyCondition(String field) throws SQLQueryObjectException{
if(field==null || "".equals(field)){
throw new SQLQueryObjectException(IS_NULL_CONDITION_DEVE_ESSERE_DIVERSO_NULL);
}
this.addWhereCondition(field+" = ''");
return this;
}
/**
* Aggiunge una condizione di ricerca (e associa un operatore logico, se le condizioni di ricerca sono piu' di una)
* es: SELECT * from tabella WHERE (field <> '')
*
* @param field Field da verificare
*/
@Override
public ISQLQueryObject addWhereIsNotEmptyCondition(String field) throws SQLQueryObjectException{
if(field==null || "".equals(field)){
throw new SQLQueryObjectException(IS_NULL_CONDITION_DEVE_ESSERE_DIVERSO_NULL);
}
this.addWhereCondition(field+" <> ''");
return this;
}
/**
* Aggiunge una condizione di ricerca in un insieme di valori
* esempio concreto: SELECT * from tabella WHERE id IN (a,b,c,d);
* 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.
*
* @param field Field su cui effettuare la select
* @param valore insieme di valori su cui effettuare il controllo
* @throws SQLQueryObjectException
*/
@Override
public ISQLQueryObject addWhereINCondition(String field,boolean stringValueType,String ... valore) throws SQLQueryObjectException{
if(valore==null || valore.length<1){
throw new SQLQueryObjectException("Deve essere fornito almeno un valore");
}
StringBuilder bf = new StringBuilder(field);
bf.append(" IN ( ");
for (int i = 0; i < valore.length; i++) {
if(i>0){
bf.append(",");
}
if(stringValueType){
bf.append("'");
bf.append(escapeStringValue(valore[i]));
bf.append("'");
}
else{
bf.append(valore[i]);
}
}
bf.append(")");
this.addWhereCondition(bf.toString());
return this;
}
/**
* Aggiunge una condizione di ricerca tra due valori
* esempio concreto: SELECT * from tabella WHERE id BEETWEEN a AND b
* 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.
*
* @param field Field su cui effettuare la select
* @param stringValueType indica se i valori devono essere trattati come stringhe o meno
* @param leftValue Valore dell'intervallo sinistro
* @param rightValue Valore dell'intervallo destro
* @return SQLQueryObjectException
* @throws SQLQueryObjectException
*/
@Override
public ISQLQueryObject addWhereBetweenCondition(String field,boolean stringValueType,String leftValue,String rightValue) throws SQLQueryObjectException{
if(leftValue==null){
throw new SQLQueryObjectException("Deve essere fornito un valore per l'intervallo sinistro");
}
if(rightValue==null){
throw new SQLQueryObjectException("Deve essere fornito un valore per l'intervallo destro");
}
StringBuilder bf = new StringBuilder(field);
bf.append(" BETWEEN ");
if(stringValueType){
bf.append("'");
bf.append(escapeStringValue(leftValue));
bf.append("'");
}
else{
bf.append(leftValue);
}
bf.append(AND_SEPARATOR);
if(stringValueType){
bf.append("'");
bf.append(escapeStringValue(rightValue));
bf.append("'");
}
else{
bf.append(rightValue);
}
this.addWhereCondition(bf.toString());
return this;
}
private String createWhereLikeCondition(String columnName,String searchPattern,boolean escape) throws SQLQueryObjectException{
if(columnName==null || "".equals(columnName))
throw new SQLQueryObjectException("Where Condition column name is null or empty string");
if(searchPattern==null || "".equals(searchPattern))
throw new SQLQueryObjectException("Where Condition searchPattern is null or empty string");
if(searchPattern.length()>1){
if(searchPattern.startsWith("'"))
searchPattern = searchPattern.substring(1);
if(searchPattern.endsWith("'"))
searchPattern = searchPattern.substring(0,searchPattern.length()-1);
}
String buildCondition = null;
if(escape){
EscapeSQLPattern escapePattern = escapePatternValue(searchPattern);
String escapeClausole = "";
if(escapePattern.isUseEscapeClausole()){
escapeClausole = ESCAPE_SEPARATOR+"'"+escapePattern.getEscapeClausole()+"'";
}
buildCondition = "( "+columnName+LIKE_SEPARATOR+"'"+escapePattern.getEscapeValue()+"'"+escapeClausole+" )";
}
else{
buildCondition = "( "+columnName+LIKE_SEPARATOR+"'"+searchPattern+"' )";
}
return buildCondition;
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (columnName LIKE 'searc"+LIKE_SEPARATOR+"rn')
*
* @param columnName
* @param searchPattern
*/
@Override
public ISQLQueryObject addWhereLikeCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return addWhereLikeCondition(columnName, searchPattern,true);
}
@Override
public ISQLQueryObject addWhereLikeCondition(String columnName,String searchPattern,boolean escape) throws SQLQueryObjectException{
String buildCondition = this.createWhereLikeCondition(columnName, searchPattern,escape);
if((buildCondition.indexOf("?")==-1) && this.conditions.contains(buildCondition))
throw new SQLQueryObjectException(WHERE_CONDITION_PREFIX+buildCondition+GIA_ESISTENTE_TRA_CONDIZIONI_WHERE);
this.conditions.add(buildCondition);
return this;
}
/**
* Ritorna una condizione di ricerca
* es: "columnName LIKE 'searchPattern'"
*
* @param columnName
* @param searchPattern
*/
@Override
public String getWhereLikeCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return this.createWhereLikeCondition(columnName, searchPattern,true);
}
@Override
public String getWhereLikeCondition(String columnName,String searchPattern,boolean escape) throws SQLQueryObjectException{
return this.createWhereLikeCondition(columnName, searchPattern,escape);
}
@Override
public String getWhereLikeCondition(String columnName,String searchPattern, LikeConfig c) throws SQLQueryObjectException{
return this.createWhereLikeCondition(columnName,searchPattern,
c.isEscape(),
c.isContains(), c.isStartsWith(), c.isEndsWith(),
c.isCaseInsensitive());
}
private String createWhereLikeCondition(String columnName,String searchPattern,
boolean escape,
boolean contains, boolean startsWith, boolean endsWith,
boolean caseInsensitive) throws SQLQueryObjectException{
if(columnName==null || "".equals(columnName))
throw new SQLQueryObjectException("Where Condition column name is null or empty string");
if(searchPattern==null || "".equals(searchPattern))
throw new SQLQueryObjectException("Where Condition searchPattern is null or empty string");
if(searchPattern.length()>1){
if(searchPattern.startsWith("'"))
searchPattern = searchPattern.substring(1);
if(searchPattern.endsWith("'"))
searchPattern = searchPattern.substring(0,searchPattern.length()-1);
}
String buildCondition = null;
if(escape){
buildCondition = createWhereLikeConditionEscapeEngine(columnName, searchPattern,
contains, startsWith, endsWith,
caseInsensitive);
}
else{
buildCondition = createWhereLikeConditionNoEscapeEngine(columnName, searchPattern,
contains, startsWith, endsWith,
caseInsensitive);
}
return buildCondition;
}
private String createWhereLikeConditionEscapeEngine(String columnName,String searchPattern,
boolean contains, boolean startsWith, boolean endsWith,
boolean caseInsensitive) throws SQLQueryObjectException {
String buildCondition = null;
if(caseInsensitive) {
buildCondition = createWhereLikeConditionEscapeEngineCaseInsensitive(columnName, searchPattern,
contains, startsWith, endsWith);
}
else {
buildCondition = createWhereLikeConditionEscapeEngineCaseSensitive(columnName, searchPattern,
contains, startsWith, endsWith);
}
return buildCondition;
}
private String createWhereLikeConditionEscapeEngineCaseInsensitive(String columnName,String searchPattern,
boolean contains, boolean startsWith, boolean endsWith) throws SQLQueryObjectException {
String buildCondition = null;
EscapeSQLPattern escapePattern = escapePatternValue(searchPattern);
String escapeClausole = "";
if(escapePattern.isUseEscapeClausole()){
escapeClausole = ESCAPE_SEPARATOR+"'"+escapePattern.getEscapeClausole()+"'";
}
if(contains) {
buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'%"+escapePattern.getEscapeValue().toLowerCase()+"%'"+escapeClausole+" )";
}
else if(startsWith) {
buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'"+escapePattern.getEscapeValue().toLowerCase()+"%'"+escapeClausole+" )";
}
else if(endsWith) {
buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'%"+escapePattern.getEscapeValue().toLowerCase()+"'"+escapeClausole+" )";
}
else {
buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'"+escapePattern.getEscapeValue().toLowerCase()+"'"+escapeClausole+" )";
}
return buildCondition;
}
private String createWhereLikeConditionEscapeEngineCaseSensitive(String columnName,String searchPattern,
boolean contains, boolean startsWith, boolean endsWith) throws SQLQueryObjectException {
String buildCondition = null;
EscapeSQLPattern escapePattern = escapePatternValue(searchPattern);
String escapeClausole = "";
if(escapePattern.isUseEscapeClausole()){
escapeClausole = ESCAPE_SEPARATOR+"'"+escapePattern.getEscapeClausole()+"'";
}
if(contains) {
buildCondition ="( "+columnName+LIKE_SEPARATOR+"'%"+escapePattern.getEscapeValue()+"%'"+escapeClausole+" )";
}
else if(startsWith) {
buildCondition ="( "+columnName+LIKE_SEPARATOR+"'"+escapePattern.getEscapeValue()+"%'"+escapeClausole+" )";
}
else if(endsWith) {
buildCondition ="( "+columnName+LIKE_SEPARATOR+"'%"+escapePattern.getEscapeValue()+"'"+escapeClausole+" )";
}
else {
buildCondition ="( "+columnName+LIKE_SEPARATOR+"'"+escapePattern.getEscapeValue()+"'"+escapeClausole+" )";
}
return buildCondition;
}
private String createWhereLikeConditionNoEscapeEngine(String columnName,String searchPattern,
boolean contains, boolean startsWith, boolean endsWith,
boolean caseInsensitive) {
String buildCondition = null;
if(caseInsensitive) {
buildCondition = createWhereLikeConditionNoEscapeEngineCaseInsensitive(columnName, searchPattern,
contains, startsWith, endsWith);
}
else {
buildCondition = createWhereLikeConditionNoEscapeEngineCaseSensitive(columnName, searchPattern,
contains, startsWith, endsWith);
}
return buildCondition;
}
private String createWhereLikeConditionNoEscapeEngineCaseInsensitive(String columnName,String searchPattern,
boolean contains, boolean startsWith, boolean endsWith) {
String buildCondition = null;
if(contains) {
buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'%"+searchPattern.toLowerCase()+"%' )";
}
else if(startsWith) {
buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'"+searchPattern.toLowerCase()+"%' )";
}
else if(endsWith) {
buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'%"+searchPattern.toLowerCase()+"' )";
}
else {
buildCondition =LOWER_PREFIX+columnName+")"+LIKE_SEPARATOR+"'"+searchPattern.toLowerCase()+"' )";
}
return buildCondition;
}
private String createWhereLikeConditionNoEscapeEngineCaseSensitive(String columnName,String searchPattern,
boolean contains, boolean startsWith, boolean endsWith) {
String buildCondition = null;
if(contains) {
buildCondition ="( "+columnName+LIKE_SEPARATOR+"'%"+searchPattern+"%' )";
}
else if(startsWith) {
buildCondition ="( "+columnName+LIKE_SEPARATOR+"'"+searchPattern+"%' )";
}
else if(endsWith) {
buildCondition ="( "+columnName+LIKE_SEPARATOR+"'%"+searchPattern+"' )";
}
else {
buildCondition ="( "+columnName+LIKE_SEPARATOR+"'"+searchPattern+"' )";
}
return buildCondition;
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (columnName LIKE 'searchPattern')
*
* @param columnName
* @param searchPattern
* @param contains true se la parola deve essere contenuta nella colonna, false se deve essere esattamente la colonna
* @param caseInsensitive
*/
@Override
public ISQLQueryObject addWhereLikeCondition(String columnName,String searchPattern, boolean contains, boolean caseInsensitive) throws SQLQueryObjectException{
return addWhereLikeCondition(columnName,searchPattern,true,contains,caseInsensitive);
}
@Override
public ISQLQueryObject addWhereLikeCondition(String columnName,String searchPattern, boolean escape, boolean contains, boolean caseInsensitive) throws SQLQueryObjectException{
String buildCondition = this.createWhereLikeCondition(columnName, searchPattern,
escape,
contains, false, false,
caseInsensitive);
if((buildCondition.indexOf("?")==-1) && this.conditions.contains(buildCondition))
throw new SQLQueryObjectException(WHERE_CONDITION_PREFIX+buildCondition+GIA_ESISTENTE_TRA_CONDIZIONI_WHERE);
this.conditions.add(buildCondition);
return this;
}
@Override
public ISQLQueryObject addWhereLikeCondition(String columnName,String searchPattern, LikeConfig likeConfig) throws SQLQueryObjectException{
String buildCondition = this.createWhereLikeCondition(columnName, searchPattern,
likeConfig.isEscape(),
likeConfig.isContains(), likeConfig.isStartsWith(), likeConfig.isEndsWith(),
likeConfig.isCaseInsensitive());
if((buildCondition.indexOf("?")==-1) && this.conditions.contains(buildCondition))
throw new SQLQueryObjectException(WHERE_CONDITION_PREFIX+buildCondition+GIA_ESISTENTE_TRA_CONDIZIONI_WHERE);
this.conditions.add(buildCondition);
return this;
}
/**
* Ritorna una condizione di ricerca
* es: "columnName LIKE 'searchPattern'"
*
* @param columnName
* @param searchPattern
* @param contains true se la parola deve essere contenuta nella colonna, false se deve essere esattamente la colonna
* @param caseInsensitive
*/
@Override
public String getWhereLikeCondition(String columnName,String searchPattern, boolean contains, boolean caseInsensitive) throws SQLQueryObjectException{
return this.createWhereLikeCondition(columnName, searchPattern,
true,
contains, false, false,
caseInsensitive);
}
@Override
public String getWhereLikeCondition(String columnName,String searchPattern,boolean escape, boolean contains, boolean caseInsensitive) throws SQLQueryObjectException{
return this.createWhereLikeCondition(columnName, searchPattern,
escape,
contains, false, false,
caseInsensitive);
}
private ISQLQueryObject addWhereCondition(String columnName,String searchPattern, DateTimePartEnum dateTimePart) throws SQLQueryObjectException{
if(columnName==null || "".equals(columnName)){
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
}
String field = this.getExtractDateTimePartFromTimestampFieldPrefix(dateTimePart)+columnName+this.getExtractDateTimePartFromTimestampFieldSuffix(dateTimePart);
this.addWhereCondition(field+" = '"+searchPattern+"'");
return this;
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (EXTRACT(YEAR FROM columnName) = 'pattern')
*
* @param columnName
* @param searchPattern
*/
@Override
public ISQLQueryObject addWhereYearCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return addWhereCondition(columnName, searchPattern, DateTimePartEnum.YEAR);
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (EXTRACT(MONTH FROM columnName) = 'pattern')
*
* @param columnName
* @param searchPattern
*/
@Override
public ISQLQueryObject addWhereMonthCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return addWhereCondition(columnName, searchPattern, DateTimePartEnum.MONTH);
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (EXTRACT(DAY FROM columnName) = 'pattern')
*
* @param columnName
* @param searchPattern
*/
@Override
public ISQLQueryObject addWhereDayCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return addWhereCondition(columnName, searchPattern, DateTimePartEnum.DAY);
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (EXTRACT(HOUR FROM columnName) = 'pattern')
*
* @param columnName
* @param searchPattern
*/
@Override
public ISQLQueryObject addWhereHourCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return addWhereCondition(columnName, searchPattern, DateTimePartEnum.HOUR);
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (EXTRACT(MINUTE FROM columnName) = 'pattern')
*
* @param columnName
* @param searchPattern
*/
@Override
public ISQLQueryObject addWhereMinuteCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return addWhereCondition(columnName, searchPattern, DateTimePartEnum.MINUTE);
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (EXTRACT(SECOND FROM columnName) = 'pattern')
*
* @param columnName
* @param searchPattern
*/
@Override
public ISQLQueryObject addWhereSecondCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return addWhereCondition(columnName, searchPattern, DateTimePartEnum.SECOND);
}
private ISQLQueryObject addWhereCondition(String columnName,String searchPattern, DayFormatEnum dayFormatEnum) throws SQLQueryObjectException{
if(columnName==null || "".equals(columnName)){
throw new SQLQueryObjectException(FIELD_DEVE_ESSERE_DIVERSO_NULL);
}
String field = this.getExtractDayFormatFromTimestampFieldPrefix(dayFormatEnum)+columnName+this.getExtractDayFormatFromTimestampFieldSuffix(dayFormatEnum);
this.addWhereCondition(field+" = '"+searchPattern+"'");
return this;
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (TO_CHAR(field, 'DAY') = 'pattern')
*
* @param columnName
* @param searchPattern
*/
@Override
public ISQLQueryObject addWhereFullDayNameCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return addWhereCondition(columnName, searchPattern, DayFormatEnum.FULL_DAY_NAME);
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (TO_CHAR(field, 'DY') = 'pattern')
*
* @param columnName
* @param searchPattern
*/
@Override
public ISQLQueryObject addWhereShortDayNameCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return addWhereCondition(columnName, searchPattern, DayFormatEnum.SHORT_DAY_NAME);
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (TO_CHAR(field, 'DDD') = 'pattern')
*
* @param columnName
* @param searchPattern
*/
@Override
public ISQLQueryObject addWhereDayOfYearCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return addWhereCondition(columnName, searchPattern, DayFormatEnum.DAY_OF_YEAR);
}
/**
* Aggiunge una condizione di ricerca
* es: SELECT * from tabella WHERE (TO_CHAR(field, 'D') = 'pattern')
*
* @param columnName
* @param searchPattern
*/
@Override
public ISQLQueryObject addWhereDayOfWeekCondition(String columnName,String searchPattern) throws SQLQueryObjectException{
return addWhereCondition(columnName, searchPattern, DayFormatEnum.DAY_OF_WEEK);
}
private String createWhereExistsCondition(boolean notExists,ISQLQueryObject sqlQueryObject)throws SQLQueryObjectException{
if(sqlQueryObject==null)
throw new SQLQueryObjectException("ISQLQueryObject, su cui viene effettuato il controllo di exists, non fornito");
if(sqlQueryObject instanceof SQLQueryObjectCore){
// http://stackoverflow.com/questions/5119190/oracle-sql-order-by-in-subquery-problems
SQLQueryObjectCore core = (SQLQueryObjectCore) sqlQueryObject;
if(core.orderBy!=null && !core.orderBy.isEmpty()){
throw new SQLQueryObjectException("ISQLQueryObject, su cui viene effettuato il controllo di exists, non deve possedere condizioni di order by");
}
if(core.offset>=0){
throw new SQLQueryObjectException("ISQLQueryObject, su cui viene effettuato il controllo di exists, non deve possedere la condizione di OFFSET");
}
}
StringBuilder bf = new StringBuilder();
if(notExists)
bf.append("NOT ");
bf.append("EXISTS (");
bf.append(sqlQueryObject.createSQLQuery());
bf.append(" )");
return bf.toString();
}
/**
* Aggiunge una condizione di ricerca con EXISTS
* La query su cui viene effettuato il controllo di exists e' definito dal parametro sqlQueryObject
* es. SELECT * from tabella WHERE [NOT] EXISTS ( sqlQueryObject.createSQLQuery() )
*
* @param notExists Indicazione se applicare la negazione all'exists
* @param sqlQueryObject query su cui viene effettuato il controllo di exists, la query viene prodotta attraverso il metodo createSQLQuery()
* @throws SQLQueryObjectException
*/
@Override
public ISQLQueryObject addWhereExistsCondition(boolean notExists,ISQLQueryObject sqlQueryObject) throws SQLQueryObjectException{
this.addWhereCondition(this.createWhereExistsCondition(notExists, sqlQueryObject));
return this;
}
/**
* Ritorna una condizione di ricerca con EXISTS
* La query su cui viene effettuato il controllo di exists e' definito dal parametro sqlQueryObject
* es. SELECT * from tabella WHERE [NOT] EXISTS ( sqlQueryObject.createSQLQuery() )
*
* @param notExists Indicazione se applicare la negazione all'exists
* @param sqlQueryObject query su cui viene effettuato il controllo di exists, la query viene prodotta attraverso il metodo createSQLQuery()
* @throws SQLQueryObjectException
*/
@Override
public String getWhereExistsCondition(boolean notExists,ISQLQueryObject sqlQueryObject) throws SQLQueryObjectException{
return this.createWhereExistsCondition(notExists, sqlQueryObject);
}
/**
* Aggiunge una condizione di ricerca con sotto-select
* La query su cui viene effettuato la ricerca della sotto-select e' definita dal parametro sqlQueryObject
* es. SELECT * from tabella WHERE [NOT] field=( sqlQueryObject.createSQLQuery() )
* esempio concreto: SELECT * from tabella WHERE id=(select rif from riferimenti);
*
* @param notExists Indicazione se applicare la negazione
* @param field Field su cui effettuare la select
* @param sqlQueryObject query su cui viene effettuato la ricerca, la query viene prodotta attraverso il metodo createSQLQuery()
* @throws SQLQueryObjectException
*/
@Override
public ISQLQueryObject addWhereSelectSQLCondition(boolean notExists,String field,ISQLQueryObject sqlQueryObject) throws SQLQueryObjectException{
this.addWhereCondition(this.createWhereSQLConditionCondition(notExists,false,field,sqlQueryObject));
return this;
}
/**
* Aggiunge una condizione di ricerca con sotto-select
* La query su cui viene effettuato la ricerca della sotto-select e' definita dal parametro sqlQueryObject
* es. SELECT * from tabella WHERE [NOT] field IN ( sqlQueryObject.createSQLQuery() )
* esempio concreto: SELECT * from tabella WHERE id IN (select rif from riferimenti);
*
* @param notExists Indicazione se applicare la negazione
* @param field Field su cui effettuare la select
* @param sqlQueryObject query su cui viene effettuato la ricerca, la query viene prodotta attraverso il metodo createSQLQuery()
* @throws SQLQueryObjectException
*/
@Override
public ISQLQueryObject addWhereINSelectSQLCondition(boolean notExists,String field,ISQLQueryObject sqlQueryObject) throws SQLQueryObjectException{
this.addWhereCondition(this.createWhereSQLConditionCondition(notExists,true,field,sqlQueryObject));
return this;
}
private String createWhereSQLConditionCondition(boolean notExists, boolean in,String field,ISQLQueryObject sqlQueryObject)throws SQLQueryObjectException{
if(sqlQueryObject==null)
throw new SQLQueryObjectException("ISQLQueryObject, su cui viene costruita la ricerca, non fornito");
if(field==null)
throw new SQLQueryObjectException("Field non fornito");
if(sqlQueryObject instanceof SQLQueryObjectCore){
// http://stackoverflow.com/questions/5119190/oracle-sql-order-by-in-subquery-problems
SQLQueryObjectCore core = (SQLQueryObjectCore) sqlQueryObject;
checkWhereSqlConditionConditionLimitOffse(in, core);
}
StringBuilder bf = new StringBuilder();
if(notExists)
bf.append("NOT ");
bf.append(field);
if(in)
bf.append(" IN ");
else
bf.append(" = ");
bf.append(" (");
bf.append(sqlQueryObject.createSQLQuery());
bf.append(" )");
return bf.toString();
}
private void checkWhereSqlConditionConditionLimitOffse(boolean in,SQLQueryObjectCore core) throws SQLQueryObjectException {
// http://stackoverflow.com/questions/5119190/oracle-sql-order-by-in-subquery-problems
if(core.orderBy!=null && !core.orderBy.isEmpty()){
throw new SQLQueryObjectException("ISQLQueryObject, su cui viene effettuato il controllo di exists, non deve possedere condizioni di order by");
}
if(core.offset>=0){
throw new SQLQueryObjectException("ISQLQueryObject, su cui viene effettuato il controllo di exists, non deve possedere la condizione di OFFSET");
}
if(!in &&
core.limit>1){
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')");
}
}
/**
* Imposta come operatore logico tra due o piu' condizioni esistenti l'AND se true, l'OR se false
*
* @param andLogicOperator
*/
@Override
public void setANDLogicOperator(boolean andLogicOperator) throws SQLQueryObjectException{
this.andLogicOperator = andLogicOperator;
} // se false viene utilizzato OR tra le condizioni
/**
* Imposta il NOT prima delle condizioni NOT ( conditions )
*
* @param not
*/
@Override
public void setNOTBeforeConditions(boolean not) throws SQLQueryObjectException{
this.notBeforeConditions = not;
} // se true viene utilizzato il NOT davanti alle condizioni
// ESCAPE
/**
* Effettua l'escape di un valore di tipo stringa
*
* @param value valore su cui effettuare l'escape
* @return valore su cui e' stato effettuato l'escape
* @throws SQLQueryObjectException
*/
@Override
public String escapeStringValue(String value) throws SQLQueryObjectException{
return SQLQueryObjectCore.getEscapeStringValue(value);
}
public static String getEscapeStringValue(String value) throws SQLQueryObjectException{
if(value==null){
throw new SQLQueryObjectException("Valore non fornito per escape");
}
// converte ' in ''
int index = value.indexOf('\'');
if(index>=0){
StringBuilder str = new StringBuilder();
char[] v = value.toCharArray();
for(int i=0; i<v.length; i++){
if(v[i]=='\''){
str.append('\'');
}
str.append(v[i]);
}
return str.toString();
}
return value;
}
/**
* Effettua l'escape di un pattern
*
* @param pattern pattern su cui effettuare l'escape
* @return pattern su cui e' stato effettuato l'escape
* @throws SQLQueryObjectException
*/
@Override
public EscapeSQLPattern escapePatternValue(String pattern)
throws SQLQueryObjectException {
EscapeSQLPattern escapeSqlPattern = new EscapeSQLPattern();
if(pattern==null){
throw new SQLQueryObjectException("Valore non fornito per escape");
}
EscapeSQLConfiguration escapeConfig = this.getEscapeSQLConfiguration();
StringBuilder str = new StringBuilder();
char[] v = pattern.toCharArray();
for(int i=0; i<v.length; i++){
if(escapeConfig.isDefaultEscape(v[i])){
str.append(escapeConfig.getEscape());
if(escapeConfig.isUseEscapeClausole()){
escapeSqlPattern.setUseEscapeClausole(true);
escapeSqlPattern.setEscapeClausole(escapeConfig.getEscape());
}
}
else if(escapeConfig.isOtherEscape(v[i])){
str.append(escapeConfig.getOtherEscapeCharacter(v[i]));
}
str.append(v[i]);
}
String returnStr = str.toString();
escapeSqlPattern.setEscapeValue(returnStr);
return escapeSqlPattern;
}
protected abstract EscapeSQLConfiguration getEscapeSQLConfiguration();
// GROUP BY
/**
* Aggiunge una condizione di GroupBy per i field con il nome sottostante.
* I field devono essere precedentemente stati inseriti come SelectField
*
* @param groupByNomeField Nome del field di raggruppamento
*/
@Override
public ISQLQueryObject addGroupBy(String groupByNomeField) throws SQLQueryObjectException{
if(groupByNomeField==null || "".equals(groupByNomeField))
throw new SQLQueryObjectException("GroupBy Condition is null or empty string");
/**
* Non e' sempre vero
* if(this.fields.contains(groupByNomeField)==false){
* throw new SQLQueryObjectException("GroupBy Condition field non e' registrati tra i select field");
}*/
/**if(this.tableAlias.size()>0){
throw new SQLQueryObjectException("Non e' possibile utilizzare alias nelle tabelle se poi si vuole usufruire della condizione GroupBy");
} IL PROBLEMA DOVREBBE ESSERE STATO RISOLTO CON LA GESTIONE DEGLI ALIAS
*/
if(this.alias.containsKey(groupByNomeField)){
this.groupBy.add(this.alias.get(groupByNomeField));
}
else{
this.groupBy.add(groupByNomeField);
}
return this;
}
public List<String> getGroupByConditions() throws SQLQueryObjectException{
if(this.groupBy!=null && !this.groupBy.isEmpty() &&
this.fields.isEmpty()){
throw new SQLQueryObjectException("Non e' possibile utilizzare condizioni di group by se non sono stati indicati select field");
}
return this.groupBy;
}
// ORDER BY
/**
* Aggiunge una condizione di OrderBy per i field con il nome sottostante.
* I field devono essere precedentemente stati inseriti come SelectField
*
* @param orderByNomeField Nome del field di ordinamento
*/
@Override
public ISQLQueryObject addOrderBy(String orderByNomeField) throws SQLQueryObjectException{
if(orderByNomeField==null || "".equals(orderByNomeField))
throw new SQLQueryObjectException("OrderBy Condition is null or empty string");
/**
* Non e' sempre vero
* if(this.fields.contains(orderByNomeField)==false){
* throw new SQLQueryObjectException("OrderBy Condition field non e' registrati tra i select field");
}*/
this.orderBy.add(orderByNomeField);
return this;
}
/**
* Aggiunge una condizione di OrderBy per i field con il nome sottostante.
* I field devono essere precedentemente stati inseriti come SelectField
*
* @param orderByNomeField Nome del field di ordinamento
* @param asc Imposta la stringa di ordinamento (Crescente:true/Decrescente:false)
*/
@Override
public ISQLQueryObject addOrderBy(String orderByNomeField, boolean asc) throws SQLQueryObjectException{
this.addOrderBy(orderByNomeField);
this.orderBySortType.put(orderByNomeField, asc);
return this;
}
/**
* Imposta la stringa di ordinamento (Crescente:true/Decrescente:false)
*/
@Override
public void setSortType(boolean sort) throws SQLQueryObjectException{
if(this.orderBy.isEmpty())
throw new SQLQueryObjectException("OrderBy Conditions non definite");
this.sortTypeAsc = sort;
}
// LIMIT E OFFSET
/**
* Aggiunge un limite ai risultati ritornati
*
* @param limit limite dei risultati ritornati
*/
@Override
public void setLimit(int limit) throws SQLQueryObjectException{
this.limit = limit;
}
public int getLimit() {
return this.limit;
}
/**
* Aggiunge un offset per i risultati ritornati
*
* @param offset offset per i risultati ritornati
*/
@Override
public void setOffset(int offset) throws SQLQueryObjectException{
this.offset = offset;
}
public int getOffset() {
return this.offset;
}
// SELECT FOR UPDATE
public boolean isSelectForUpdate() {
return this.selectForUpdate;
}
@Override
public void setSelectForUpdate(boolean selectForUpdate) throws SQLQueryObjectException {
this.selectForUpdate = selectForUpdate;
}
protected void checkSelectForUpdate(boolean update,boolean delete, boolean union) throws SQLQueryObjectException{
if(this.selectForUpdate){
String tipo = null;
if(update){
tipo = "UPDATE";
}
else if(delete){
tipo = "DELETE";
}
else if(union){
tipo = "UNION";
}
else if(!this.getGroupByConditions().isEmpty()){
tipo = "GROUP BY";
}
else if(this.isSelectDistinct()){
tipo = "DISTINCT";
}
else if(this.limit>=0){
tipo = "LIMIT";
}
else if(this.offset>=0){
tipo = "OFFSET";
}
if(tipo!=null)
throw new SQLQueryObjectException("Utilizzo dell'opzione 'FOR UPDATE' non permesso con il comando "+tipo);
}
}
// GENERAZIONE SQL
/**
* Crea una SQL Query con i dati dell'oggetto
*
* @return SQL Query
*/
/**@Override
public abstract String createSQLQuery() throws SQLQueryObjectException;*/
@Override
public String toString(){
try{
return this.createSQLQuery();
}catch(Exception e){
return "Oggetto non corretto: "+e.getMessage();
}
}
protected void checkUnionField(boolean count,ISQLQueryObject... sqlQueryObject)throws SQLQueryObjectException{
if(count){
checkUnionFieldCount();
}
if(this.offset>=0 &&
this.fields.isEmpty()) {
throw new SQLQueryObjectException("Non e' possibile usare offset se non e' stato indicato alcun field nella select piu' esterna della union");
}
if(this.limit>0 &&
this.fields.isEmpty()) {
throw new SQLQueryObjectException("Non e' possibile usare limit se non e' stato indicato alcun field nella select piu' esterna della union");
}
if(this.distinct){
throw new SQLQueryObjectException("Non e' possibile usare distinct nella select piu' esterna della union (utilizza il parametro boolean unionAll)");
}
if(sqlQueryObject==null || sqlQueryObject.length<=0){
throw new SQLQueryObjectException("Parametro is null");
}
if(sqlQueryObject.length==1){
throw new SQLQueryObjectException("Parametro contiene un solo sqlQueryObject (minimo 2)");
}
// Check presenza fields
checkUnionFieldExists(sqlQueryObject);
// Check nomi fields
checkUnionFieldNames(sqlQueryObject);
// 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
checkUnionFieldOrderOffset(sqlQueryObject);
// Check Select For Update
if(this.selectForUpdate){
throw new SQLQueryObjectException("Non è possibile abilitare il comando 'selectForUpdate' con la UNION");
}
}
protected void checkUnionFieldCount() throws SQLQueryObjectException{
if(this.orderBy!=null && !this.orderBy.isEmpty()){
throw new SQLQueryObjectException("Non e' possibile usare order by in una count");
}
if(this.limit>0){
throw new SQLQueryObjectException("Non e' possibile usare limit in una count");
}
if(this.offset>=0){
throw new SQLQueryObjectException("Non e' possibile usare offset in una count");
}
}
protected void checkUnionFieldExists(ISQLQueryObject... sqlQueryObject)throws SQLQueryObjectException{
for(int i=0;i<sqlQueryObject.length;i++){
ISQLQueryObject sqlQueryObjectDaVerificare = sqlQueryObject[i];
List<String> nomiFieldSqlQueryObjectDaVerificare = sqlQueryObjectDaVerificare.getFieldsName();
if(nomiFieldSqlQueryObjectDaVerificare==null || nomiFieldSqlQueryObjectDaVerificare.isEmpty()){
throw new SQLQueryObjectException("La select numero "+(i+1)+" non possiede fields?");
}
}
}
protected void checkUnionFieldNames(ISQLQueryObject... sqlQueryObject)throws SQLQueryObjectException{
/** for(int i=0;i<sqlQueryObject.length;i++){
// System.out.println("CHECK ["+i+"] ...");
// List<String> nomiFieldSqlQueryObjectDaVerificare = sqlQueryObject[i].getFieldsName();
// for (String string : nomiFieldSqlQueryObjectDaVerificare) {
// System.out.println("\t-"+string);
// }
// }*/
for(int i=0;i<sqlQueryObject.length;i++){
List<String> nomiFieldSqlQueryObjectDaVerificare = sqlQueryObject[i].getFieldsName();
String [] nomi = nomiFieldSqlQueryObjectDaVerificare.toArray(new String[1]);
for(int indiceField =0; indiceField<nomi.length;indiceField++){
String fieldDaVerificare = nomi[indiceField];
for(int altriSqlObject=0;altriSqlObject<sqlQueryObject.length;altriSqlObject++){
if(altriSqlObject==i){
// e' l'oggetto in questione
continue;
}
if( (!sqlQueryObject[altriSqlObject].getFieldsName().contains(fieldDaVerificare)) &&
(!sqlQueryObject[altriSqlObject].getFieldsName().contains("*")) ){
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)");
}
}
}
}
}
protected void checkUnionFieldOrderOffset(ISQLQueryObject... sqlQueryObject)throws SQLQueryObjectException{
for(int i=0;i<sqlQueryObject.length;i++){
SQLQueryObjectCore sqlQueryObjectDaVerificare = (SQLQueryObjectCore) sqlQueryObject[i];
if(sqlQueryObjectDaVerificare.orderBy!=null && !sqlQueryObjectDaVerificare.orderBy.isEmpty() &&
sqlQueryObjectDaVerificare.offset<0){
/**throw new SQLQueryObjectException("La select numero "+(i+1)+" per poter essere utilizzata nella UNION, siccome presenta condizioni di ordinamento, deve specificare anche l'offset");*/
sqlQueryObjectDaVerificare.setOffset(0); // Se viene messo il limit, l'offset cmq parte da 0
}
}
}
/* ---------------- UPDATE ------------------ */
/**
* Definisce la tabella su cui deve essere effettuato l'update
* es: UPDATE table set ...
*
* @param nomeTabella Nome della tabella
*/
@Override
public ISQLQueryObject addUpdateTable(String nomeTabella) throws SQLQueryObjectException{
if(nomeTabella==null || "".equals(nomeTabella))
throw new SQLQueryObjectException("Nome tabella is null or empty string");
this.updateTable = nomeTabella;
return this;
}
/**
* Aggiunge un field per l'update
* es: UPDATE table set nomeField=valueField WHERE ...
*
* @param nomeField Nome del Field
*/
@Override
public ISQLQueryObject addUpdateField(String nomeField,String valueField) throws SQLQueryObjectException{
if(nomeField==null || "".equals(nomeField))
throw new SQLQueryObjectException(FIELD_NAME_IS_NULL_OR_EMPTY);
if(valueField==null)
throw new SQLQueryObjectException("Field value is null");
if(this.updateFieldsName.contains(nomeField)){
throw new SQLQueryObjectException(FIELD_NAME_PREFIX+nomeField+" gia inserito tra gli update fields");
}else{
this.updateFieldsName.add(nomeField);
this.updateFieldsValue.add(valueField);
}
return this;
}
@Override
public ISQLQueryObject addUpdateField(String nomeField,Case caseValue) throws SQLQueryObjectException{
if(nomeField==null || "".equals(nomeField))
throw new SQLQueryObjectException(FIELD_NAME_IS_NULL_OR_EMPTY);
if(this.updateFieldsName.contains(nomeField)){
throw new SQLQueryObjectException(FIELD_NAME_PREFIX+nomeField+" gia inserito tra gli update fields");
}else{
String caseCondition = getCaseCondition(caseValue);
this.updateFieldsName.add(nomeField);
this.updateFieldsValue.add(caseCondition);
}
return this;
}
protected String getPrefixCastValue(CastColumnType type, int length) {
if(type!=null && length>0) {
// nop
}
return "";
}
protected String getSuffixCastValue(CastColumnType type, int length) {
if(type!=null || length>0) {
// nop
}
return "";
}
@Override
public String createSQLUpdate() throws SQLQueryObjectException{
if(this.updateTable==null)
throw new SQLQueryObjectException("Nome Tabella per l'aggiornamento non definito");
if(this.updateFieldsName.isEmpty())
throw new SQLQueryObjectException("Nessuna coppia nome/valore da aggiornare presente");
if(this.updateFieldsName.size()!= this.updateFieldsValue.size()){
throw new SQLQueryObjectException("FieldsName.size["+this.updateFieldsName.size()+"] <> FieldsValue.size["+this.updateFieldsValue.size()+"]");
}
if(this.forceSelectForUpdateDisabledForNotQueryMethod){
// Per permettere di usare l'oggetto sqlQueryObject con più comandi
boolean oldValueSelectForUpdate = this.selectForUpdate;
try{
this.selectForUpdate = false;
return this.createSQLUpdateEngine();
}finally{
this.selectForUpdate = oldValueSelectForUpdate;
}
}
else{
return this.createSQLUpdateEngine();
}
}
protected abstract String createSQLUpdateEngine() throws SQLQueryObjectException;
/* ---------------- INSERT ------------------ */
/**
* Definisce la tabella su cui deve essere effettuato l'insert
* es: INSERT INTO table (XX) VALUES (VV)
*
* @param nomeTabella Nome della tabella
*/
@Override
public ISQLQueryObject addInsertTable(String nomeTabella) throws SQLQueryObjectException{
if(nomeTabella==null || "".equals(nomeTabella))
throw new SQLQueryObjectException("Nome tabella is null or empty string");
this.insertTable = nomeTabella;
return this;
}
/**
* Aggiunge un field per la insert
* es: INSERT INTO table (nomeField) VALUES (valueField)
*
* @param nomeField Nome del Field
*/
@Override
public ISQLQueryObject addInsertField(String nomeField,String valueField) throws SQLQueryObjectException{
if(nomeField==null || "".equals(nomeField))
throw new SQLQueryObjectException(FIELD_NAME_IS_NULL_OR_EMPTY);
if(valueField==null)
throw new SQLQueryObjectException("Field value is null");
if(this.insertFieldsName.contains(nomeField)){
throw new SQLQueryObjectException(FIELD_NAME_PREFIX+nomeField+" gia inserito tra gli insert fields");
}else{
this.insertFieldsName.add(nomeField);
this.insertFieldsValue.add(valueField);
}
return this;
}
/**
* Crea una SQL per una operazione di Insert con i dati dell'oggetto
*
* @return SQL per una operazione di Insert
*/
@Override
public String createSQLInsert() throws SQLQueryObjectException{
if(this.insertTable==null)
throw new SQLQueryObjectException("Nome Tabella per l'inserimento non definito");
if(this.insertFieldsName.isEmpty())
throw new SQLQueryObjectException("Nessuna coppia nome/valore da inserire presente");
if(this.insertFieldsName.size()!= this.insertFieldsValue.size()){
throw new SQLQueryObjectException("FieldsName.size <> FieldsValue.size");
}
if(this.forceSelectForUpdateDisabledForNotQueryMethod){
// Per permettere di usare l'oggetto sqlQueryObject con più comandi
boolean oldValueSelectForUpdate = this.selectForUpdate;
try{
this.selectForUpdate = false;
return this.createSQLInsertEngine();
}finally{
this.selectForUpdate = oldValueSelectForUpdate;
}
}
else{
return this.createSQLInsertEngine();
}
}
private String createSQLInsertEngine() {
StringBuilder bf = new StringBuilder();
bf.append("INSERT INTO ");
bf.append(this.insertTable);
bf.append(" (");
for(int i=0; i<this.insertFieldsName.size(); i++){
if(i>0)
bf.append(",");
bf.append(this.insertFieldsName.get(i));
}
bf.append(") VALUES (");
for(int i=0; i<this.insertFieldsValue.size(); i++){
if(i>0)
bf.append(",");
bf.append(this.insertFieldsValue.get(i));
}
bf.append(")");
return bf.toString();
}
/* ---------------- DELETE ------------------ */
/**
* Aggiunge una tabella di ricerca del from
* es: DELETE from tabella
*
* @param tabella
*/
@Override
public ISQLQueryObject addDeleteTable(String tabella) throws SQLQueryObjectException{
checkDeleteTable(tabella);
this.addFromTable(tabella);
return this;
}
@Override
public String createSQLDelete() throws SQLQueryObjectException {
// Table dove effettuare la ricerca 'FromTable'
if(this.tables.isEmpty()){
throw new SQLQueryObjectException("Non e' possibile creare un comando di delete senza aver definito le tabelle su cui apportare l'eliminazione dei dati");
}else{
Iterator<String> it = this.tables.iterator();
while(it.hasNext()){
String table = it.next();
checkDeleteTable(table);
}
}
if(this.forceSelectForUpdateDisabledForNotQueryMethod){
// Per permettere di usare l'oggetto sqlQueryObject con più comandi
boolean oldValueSelectForUpdate = this.selectForUpdate;
try{
this.selectForUpdate = false;
return this.createSQLDeleteEngine();
}finally{
this.selectForUpdate = oldValueSelectForUpdate;
}
}
else{
return this.createSQLDeleteEngine();
}
}
protected abstract String createSQLDeleteEngine() throws SQLQueryObjectException;
private void checkDeleteTable(String tabella) throws SQLQueryObjectException{
// Controllo quelli standard (da fare per impostare il controllo in ogni classe)
if(tabella.contains(" as ") || tabella.contains(" ")){
throw new SQLQueryObjectException("Non e' possibile utilizzare tabelle definite tramite alias in caso di delete");
}
List<String> asModeSupportati = this.getSupportedAliasesTable();
for (Iterator<?> iterator = asModeSupportati.iterator(); iterator.hasNext();) {
String aliasMode = (String) iterator.next();
if(tabella.contains(aliasMode)){
throw new SQLQueryObjectException("Non e' possibile utilizzare tabelle definite tramite alias in caso di delete");
}
}
}
/* ---------------- WHERE CONDITIONS ------------------ */
@Override
public String createSQLConditions() throws SQLQueryObjectException{
if(this.conditions==null)
throw new SQLQueryObjectException("Condizioni non definite");
if(this.conditions.isEmpty())
throw new SQLQueryObjectException("Nessuna condizione presente");
if(this.forceSelectForUpdateDisabledForNotQueryMethod){
// Per permettere di usare l'oggetto sqlQueryObject con più comandi
boolean oldValueSelectForUpdate = this.selectForUpdate;
try{
this.selectForUpdate = false;
return this.createSQLConditionsEngine();
}finally{
this.selectForUpdate = oldValueSelectForUpdate;
}
}
else{
return this.createSQLConditionsEngine();
}
}
protected abstract String createSQLConditionsEngine() throws SQLQueryObjectException;
/* ---------------- NEW SQL QUERY OBJECT ------------------ */
/**
* Inizializza un nuovo SQLQueryObject
*
* @return SQLQueryObject
*
* @throws SQLQueryObjectException
*/
@Override
public ISQLQueryObject newSQLQueryObject() throws SQLQueryObjectException{
return SQLObjectFactory.createSQLQueryObject(this.tipoDatabase);
}
/**
* Indicazione sul tipo di database
*
* @return tipo di database
*
* @throws SQLQueryObjectException
*/
@Override
public String getTipoDatabase() throws SQLQueryObjectException{
return this.tipoDatabase.toString();
}
/**
* Indicazione sul tipo di database
*
* @return tipo di database
*
* @throws SQLQueryObjectException
*/
@Override
public TipiDatabase getTipoDatabaseOpenSPCoop2() throws SQLQueryObjectException{
return this.tipoDatabase;
}
}