aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/database/NamedParameterStatement.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/database/NamedParameterStatement.java')
-rw-r--r--src/org/traccar/database/NamedParameterStatement.java274
1 files changed, 192 insertions, 82 deletions
diff --git a/src/org/traccar/database/NamedParameterStatement.java b/src/org/traccar/database/NamedParameterStatement.java
index 850462b2c..dcf041809 100644
--- a/src/org/traccar/database/NamedParameterStatement.java
+++ b/src/org/traccar/database/NamedParameterStatement.java
@@ -15,6 +15,7 @@
*/
package org.traccar.database;
+import javax.sql.DataSource;
import java.sql.*;
import java.util.*;
import java.util.Date;
@@ -25,9 +26,195 @@ public class NamedParameterStatement {
private final String parsedQuery;
- public NamedParameterStatement(String query) {
- indexMap = new HashMap<String, List<Integer>>();
- parsedQuery = parse(query, indexMap);
+ private final DataSource dataSource;
+
+ private final int autoGeneratedKeys;
+
+ public interface ResultSetProcessor<T> {
+ T processNextRow(ResultSet rs) throws SQLException;
+ }
+
+ public class Params {
+ Map<String, Object> values;
+ Map<String, Integer> types;
+
+ public Params setInt(String name, Integer value) {
+ setType(name, Types.INTEGER);
+ return setValue(name, value);
+ }
+
+ public Params setLong(String name, Long value) {
+ setType(name, Types.INTEGER);
+ return setValue(name, value);
+ }
+
+ public Params setString(String name, String value) {
+ setType(name, Types.VARCHAR);
+ return setValue(name, value);
+ }
+
+ public Params setDouble(String name, Double value) {
+ setType(name, Types.DOUBLE);
+ return setValue(name, value);
+ }
+
+ public Params setTimestamp(String name, Date value) {
+ setType(name, Types.TIMESTAMP);
+ return setValue(name, value);
+ }
+
+ public Params setBoolean(String name, Boolean value) {
+ setType(name, Types.BOOLEAN);
+ return setValue(name, value);
+ }
+
+ private void setType(String name, Integer type) {
+ if (types == null) {
+ types = new HashMap<String, Integer>();
+ }
+ types.put(name, type);
+ }
+
+ private Params setValue(String name, Object value) {
+ if (values == null) {
+ values = new HashMap<String, Object>();
+ }
+ values.put(name, value);
+ return this;
+ }
+
+ public <T> List<T> executeQuery(ResultSetProcessor<T> processor) throws SQLException {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+
+ List<T> result = new LinkedList<T>();
+
+ try {
+ conn = dataSource.getConnection();
+ stmt = conn.prepareStatement(parsedQuery);
+
+ setParams(stmt);
+
+ rs = stmt.executeQuery();
+ while (rs.next()) {
+ result.add(processor.processNextRow(rs));
+ }
+ } finally {
+ closeQuietly(conn, stmt, rs);
+ }
+
+ return result;
+ }
+
+ public <T> List<T> executeUpdate(ResultSetProcessor<T> processor) throws SQLException {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+
+ try {
+ conn = dataSource.getConnection();
+ stmt = conn.prepareStatement(parsedQuery, autoGeneratedKeys);
+
+ setParams(stmt);
+
+ stmt.executeUpdate();
+
+ if (autoGeneratedKeys == Statement.RETURN_GENERATED_KEYS) {
+ rs = stmt.getGeneratedKeys();
+ List<T> result = new LinkedList<T>();
+ while (rs.next()) {
+ result.add(processor.processNextRow(rs));
+ }
+ return result;
+ }
+ } finally {
+ closeQuietly(conn, stmt, rs);
+ }
+
+ return null;
+ }
+
+ public void executeUpdate() throws SQLException {
+ executeUpdate(null);
+ }
+
+ private void setParams(PreparedStatement stmt) throws SQLException {
+ if (values == null) {
+ return;
+ }
+
+ for (Map.Entry<String, Object> entry : values.entrySet()) {
+ String name = entry.getKey();
+ Object value = entry.getValue();
+ int type = types.get(name);
+
+ List<Integer> indexList = indexMap.get(name);
+ if (indexList != null) for (Integer index: indexList) {
+ if (value == null) {
+ stmt.setNull(index, type);
+ } else {
+ switch (type) {
+ case Types.INTEGER:
+ if (value instanceof Long) {
+ stmt.setLong(index, (Long) value);
+ } else if (value instanceof Integer) {
+ stmt.setInt(index, (Integer) value);
+ } else {
+ throw new IllegalArgumentException("Unknown integer value: " + value.getClass());
+ }
+ break;
+ case Types.VARCHAR:
+ stmt.setString(index, (String) value);
+ break;
+ case Types.TIMESTAMP:
+ stmt.setTimestamp(index, new Timestamp(((Date) value).getTime()));
+ break;
+ case Types.DOUBLE:
+ stmt.setDouble(index, (Double) value);
+ break;
+ case Types.BOOLEAN:
+ stmt.setBoolean(index, (Boolean) value);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private void closeQuietly(Connection conn, Statement stmt, ResultSet rs) {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException sqex) {
+ }
+ }
+
+ if (stmt != null) {
+ try {
+ stmt.close();
+ } catch (SQLException sqex) {
+ }
+ }
+
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (SQLException sqex) {
+ }
+ }
+ }
+ }
+
+ public NamedParameterStatement(String query, DataSource dataSource) {
+ this(query, dataSource, Statement.NO_GENERATED_KEYS);
+ }
+
+ public NamedParameterStatement(String query, DataSource dataSource, int autoGeneratedKeys) {
+ this.indexMap = new HashMap<String, List<Integer>>();
+ this.parsedQuery = parse(query, indexMap);
+ this.dataSource = dataSource;
+ this.autoGeneratedKeys = autoGeneratedKeys;
}
static String parse(String query, Map<String, List<Integer>> paramMap) {
@@ -83,84 +270,7 @@ public class NamedParameterStatement {
return parsedQuery.toString();
}
- public PreparedStatement prepare(Connection connection, int autoGeneratedKeys) throws SQLException {
- return connection.prepareStatement(parsedQuery, autoGeneratedKeys);
- }
-
- public PreparedStatement prepare(Connection connection) throws SQLException {
- return prepare(connection, Statement.NO_GENERATED_KEYS);
- }
-
- public void setInt(PreparedStatement statement, String name, Integer value) throws SQLException {
-
- List<Integer> indexList = indexMap.get(name);
- if (indexList != null) for (Integer index: indexList) {
- if (value != null) {
- statement.setInt(index, value);
- } else {
- statement.setNull(index, Types.INTEGER);
- }
- }
- }
-
- public void setLong(PreparedStatement statement, String name, Long value) throws SQLException {
-
- List<Integer> indexList = indexMap.get(name);
- if (indexList != null) for (Integer index: indexList) {
- if (value != null) {
- statement.setLong(index, value);
- } else {
- statement.setNull(index, Types.INTEGER);
- }
- }
+ public Params prepare() {
+ return new Params();
}
-
- public void setBoolean(PreparedStatement statement, String name, Boolean value) throws SQLException {
-
- List<Integer> indexList = indexMap.get(name);
- if (indexList != null) for (Integer index: indexList) {
- if (value != null) {
- statement.setBoolean(index, value);
- } else {
- statement.setNull(index, Types.BOOLEAN);
- }
- }
- }
-
- public void setDouble(PreparedStatement statement, String name, Double value) throws SQLException {
-
- List<Integer> indexList = indexMap.get(name);
- if (indexList != null) for (Integer index: indexList) {
- if (value != null) {
- statement.setDouble(index, value);
- } else {
- statement.setNull(index, Types.DOUBLE);
- }
- }
- }
-
- public void setTimestamp(PreparedStatement statement, String name, Date value) throws SQLException {
-
- List<Integer> indexList = indexMap.get(name);
- if (indexList != null) for (Integer index: indexList) {
- if (value != null) {
- statement.setTimestamp(index, new Timestamp(value.getTime()));
- } else {
- statement.setNull(index, Types.TIMESTAMP);
- }
- }
- }
-
- public void setString(PreparedStatement statement, String name, String value) throws SQLException {
-
- List<Integer> indexList = indexMap.get(name);
- if (indexList != null) for (Integer index: indexList) {
- if (value != null) {
- statement.setString(index, value);
- } else {
- statement.setNull(index, Types.VARCHAR);
- }
- }
- }
-
}