Commit eda4c510 authored by Nico Mack's avatar Nico Mack

Added array extrapolation feature to SqlExecutor

parent d3a27161
......@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>tulip-cps</artifactId>
<version>1.4.0</version>
<version>1.5.0</version>
<name>TULIP Complex Problem Solving</name>
<licenses>
......@@ -47,7 +47,7 @@
<dependency>
<groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>tulip</artifactId>
<version>2.4.0</version>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>maven2.dk.ange</groupId>
......@@ -67,12 +67,12 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8</version>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8</version>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
......
......@@ -211,6 +211,8 @@ public class EquationSystemBuilder {
variable = (Variable<T>) Class.forName(variableClass)
.getConstructor(String.class, String.class)
.newInstance(name, value);
if (!Strings.isNullOrEmpty(value))
variable.setValue(variable.valueFromString(value));
break;
case Externalization.SPATIAL_TYPE:
......@@ -230,6 +232,8 @@ public class EquationSystemBuilder {
variable = (Variable<T>) Class.forName(variableClass)
.getConstructor(String.class, String.class)
.newInstance(name, unit);
if (!Strings.isNullOrEmpty(value))
variable.setValue(variable.valueFromString(value));
break;
}
......
......@@ -22,13 +22,15 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.beans.PropertyVetoException;
import java.sql.Array;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -59,11 +61,24 @@ public class SqlExecutor extends Executor {
private static final String SQL_USER_NAME = "sql.user.name"; //$NON-NLS-1$
private static final String SQL_USER_PASSWORD = "sql.user.password"; //$NON-NLS-1$
private static final Pattern SQL_VAR_PATTERN = Pattern.compile("\\$\\{([a-z0-9\\-_]+)\\}", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
private static final Pattern SQL_VAR_PATTERN = Pattern.compile("([\\$@])\\{([a-z0-9\\-_]+)\\}", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
private static Logger LOGGER = LoggerFactory.getLogger(SqlExecutor.class.getSimpleName());
private static final int MAX_CONNECTION_ATTEMPTS = 3;
private static HashMap<Class<?>, String> JavaToJdbcMapping = new HashMap<>();
static {
JavaToJdbcMapping.put(String.class, "varchar"); //$NON-NLS-1$
JavaToJdbcMapping.put(Integer.class, "integer"); //$NON-NLS-1$
JavaToJdbcMapping.put(Double.class, "double"); //$NON-NLS-1$
JavaToJdbcMapping.put(Float.class, "real"); //$NON-NLS-1$
JavaToJdbcMapping.put(Date.class, "timestamp"); //$NON-NLS-1$
JavaToJdbcMapping.put(Time.class, "time"); //$NON-NLS-1$
}
private static final String SCALAR = "$"; //$NON-NLS-1$
private static final String VECTOR = "@"; //$NON-NLS-1$
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
......@@ -160,11 +175,13 @@ public class SqlExecutor extends Executor {
*/
// ---------------------------------------------------------------------------
private String interpolate(String query, List<String> placeholders, boolean positionalParameters) {
private String interpolate(String query, List<String> placeholders, Map<String, Object> parameters, boolean positionalParameters) {
Matcher interpolator;
String type;
String variable;
int position = 0;
StringBuffer interpolated;
int index = 1;
placeholders.clear();
interpolator = SQL_VAR_PATTERN.matcher(query);
......@@ -173,13 +190,42 @@ public class SqlExecutor extends Executor {
while (interpolator.find()) {
interpolated.append(query.substring(position, interpolator.start()));
position = interpolator.start();
variable = interpolator.group(1);
type = interpolator.group(1);
variable = interpolator.group(2);
if ((variable != null) && (variable.length() > 0)) {
placeholders.add(variable);
interpolated.append("?"); //$NON-NLS-1$
if (positionalParameters)
interpolated.append(placeholders.size());
if (SCALAR.equals(type)) {
interpolated.append("?"); //$NON-NLS-1$
if (positionalParameters)
interpolated.append(index++);
}
if (VECTOR.equals(type)) {
Object value = parameters.get(variable);
if (value instanceof Collection) {
Collection<?> collection = (Collection<?>) value;
String separator = "";
if (collection.size() > 0) {
for (int count = 0; count < collection.size(); count++) {
interpolated.append(separator);
interpolated.append("?");
if (positionalParameters)
interpolated.append(index++);
separator = ",";
}
} else {
interpolated.append("?"); //$NON-NLS-1$
if (positionalParameters)
interpolated.append(index++);
}
} else {
interpolated.append("?"); //$NON-NLS-1$
if (positionalParameters)
interpolated.append(index++);
}
}
} else {
interpolated.append(interpolated.substring(interpolator.start(), interpolator.end()));
}
......@@ -197,14 +243,22 @@ public class SqlExecutor extends Executor {
for (String placeholder : placeholders) {
if (context.containsKey(placeholder)) {
Object value = context.get(placeholder);
if (value instanceof Array)
statement.setArray(index, (Array) value);
else
statement.setObject(index, value);
if (value instanceof Collection) {
Collection<?> collection = (Collection<?>) value;
if (collection.size() > 0) {
for (Object item : collection) {
statement.setObject(index++, item);
}
} else {
statement.setObject(index++, null);
}
} else {
statement.setObject(index++, value);
}
} else {
LOGGER.warn("Query requires the parameter {} which is not available in context!", placeholder); //$NON-NLS-1$
}
index++;
}
return statement;
}
......@@ -304,7 +358,7 @@ public class SqlExecutor extends Executor {
long elapsed = System.currentTimeMillis();
Connection connection = this.getConnectionFromPool();
List<String> variables = new ArrayList<String>();
String queryString = this.interpolate(script, variables, false);
String queryString = this.interpolate(script, variables, this.parameters, false);
boolean success = false;
if (connection != null) {
......
......@@ -21,6 +21,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.regex.Pattern;
/**
* @author mack
......@@ -28,13 +29,40 @@ import java.util.Vector;
* @version [major].[minor].[micro]
* @param <B>
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class VectorVariable<B> extends Variable<List<B>> implements Collection<B> {
private static final Pattern VECTOR_PATTERN = Pattern.compile("\\[\\s*(.*?)\\s*\\]", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
private static final Pattern VECTOR_SPLITTER_PATTERN = Pattern.compile("([+-]?[a-z0-9\\._]+)(\\s*,[+-]?[a-z0-9\\._]+)*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
public VectorVariable(String name, String unit) {
super(Externalization.VECTOR_TYPE, name, unit);
value = new ArrayList<B>();
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitives *
// ***************************************************************************
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
public Class<?> getClassOfValues() {
if (!value.isEmpty()) {
return value.get(0).getClass();
......@@ -160,8 +188,23 @@ public class VectorVariable<B> extends Variable<List<B>> implements Collection<B
/** {@inheritDoc} */
@Override
public List<B> valueFromString(String stringValue) {
// TODO Auto-generated method stub
return null;
if (stringValue == null)
return null;
List<B> values = new ArrayList<>();
// First check whether string complies with array string representation.
// Matcher arrayMatcher = VECTOR_PATTERN.matcher(stringValue);
// if (arrayMatcher.matches()) {
// Matcher arraySplitter = VECTOR_SPLITTER_PATTERN.matcher(arrayMatcher.group(1));
// if (arraySplitter.matches()) {
// for (int i = 0; i < arraySplitter.groupCount(); i++) {
// values.add((B) arraySplitter.group(i));
// }
// }
// }
return values;
}
/** {@inheritDoc} */
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2017. All rights reserved. If you wish
* to use this code for any purpose, please contact the author(s).
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lu.list.itis.dkd.tui.cps.variable;
import static org.junit.Assert.assertEquals;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
public class VectorVariableTest {
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {}
@Test
public void test() {
VectorVariable<Double> variable = new VectorVariable<>("test", "n/a");
List<Double> fromString = variable.valueFromString("[ 1, 2, 3.5, -0.443503]");
assertEquals(4, fromString.size());
assertEquals(1d, fromString.get(0).doubleValue(), 0.0001);
assertEquals(2d, fromString.get(1).doubleValue(), 0.0001);
assertEquals(3.5d, fromString.get(2).doubleValue(), 0.0001);
assertEquals(-0.443503d, fromString.get(3).doubleValue(), 0.0001);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment