/*******************************************************************************
* Copyright (c) 2012-2015 INRIA.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Generoso Pagano - initial API and implementation
******************************************************************************/
package fr.inria.soctrace.lib.query.conditions;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import fr.inria.soctrace.lib.model.utils.SoCTraceException;
import fr.inria.soctrace.lib.query.SelfDefiningElementQuery;
import fr.inria.soctrace.lib.query.SelfDefiningElementQuery.ParamType;
import fr.inria.soctrace.lib.query.ValueListString;
import fr.inria.soctrace.lib.query.conditions.ConditionsConstants.ComparisonOperation;
import fr.inria.soctrace.lib.storage.DBObject;
import fr.inria.soctrace.lib.utils.IdManager;
/**
* Simple expression describing a condition involving a
* self-defining-elements parameter.
*
* Even if the self-defining-pattern stores the name of a
* parameter and its value in two different tables (xParamType
* and xParam), this class provide a simpler interface allowing
* the user to specify a condition with the format:
* <param_name> <comparison_operator> <param_value>
* (e.g. ADDRESS = 0xbf068544)
*
* @author "Generoso Pagano <generoso.pagano@inria.fr>"
*
*/
public class ParamSimpleCondition implements IParamCondition {
private String name;
private ComparisonOperation op;
private String value;
private boolean numericComparisonSet;
private boolean isNumericComparison;
/**
* Create a simple parameter condition: <name><operation><value> (e.g. X >= 3)
* @param name name of the parameter
* @param op comparison operation
* @param value value to compare with
*/
public ParamSimpleCondition(String name, ComparisonOperation op, String value) {
this.name = name;
this.op = op;
this.value = value;
this.numericComparisonSet = false;
this.isNumericComparison = false;
}
/**
* Set the numeric comparison flag.
* @param numeric value to set
*/
public void setNumericComparison(boolean numeric) {
this.numericComparisonSet = true;
this.isNumericComparison = numeric;
}
/**
* Returns a list of 'Element' ID.
* E.g.: "ID IN ( 1, 2, 3)"
*
* If the list is empty, the list actually returned
* contains only a reserved value which cannot be a
* valid ID.
*
* Note: a numeric comparison is performed if the type
* of the param is INTEGER or BIGINT, or if the corresponding
* flag is set.
*/
@Override
public String getSQLString(SelfDefiningElementQuery access, int typeId) throws SoCTraceException {
ParamType param = access.getParamType(name, typeId);
if (param==null)
return "ID IN ( "+ String.valueOf(IdManager.RESERVED_NO_ID) +" )";
String elementName = access.getElementTableName();
StringBuilder sb = new StringBuilder("SELECT ");
sb.append(elementName+"_ID");
sb.append(" FROM ");
sb.append(elementName+"_PARAM");
sb.append(" WHERE ");
// check numeric comparison
String valueAttribute;
if (numericComparisonSet) {
if (isNumericComparison)
valueAttribute = "CAST(VALUE AS SIGNED)";
else
valueAttribute = "VALUE";
} else {
if (param.type.equals("INTEGER") || param.type.equals("BIGINT") )
valueAttribute = "CAST(VALUE AS SIGNED)";
else
valueAttribute = "VALUE";
}
// where clause
// fix for IN/BETWEEN operator: no ''
String valueString;
if (op==ComparisonOperation.IN || op==ComparisonOperation.BETWEEN)
valueString = valueAttribute + op.toString() + value + ")";
else
valueString = valueAttribute + op.toString() + "'" + value + "')";
sb.append("("+elementName+"_PARAM_TYPE_ID="+param.id+
" AND "+valueString);
try {
DBObject dbObj = access.getDBObject();
Statement stm = dbObj.getConnection().createStatement();
ResultSet rs = stm.executeQuery(sb.toString());
ValueListString vls = new ValueListString();
while (rs.next()) {
vls.addValue(rs.getString(1));
}
if (vls.size() > 0)
return "ID IN " + vls.getValueString();
else
return "ID IN ( "+ String.valueOf(IdManager.RESERVED_NO_ID) +" )";
} catch (SQLException e) {
throw new SoCTraceException(e);
}
}
}