diff options
Diffstat (limited to 'src/org/traccar/database/NamedParameterStatement.java')
-rw-r--r-- | src/org/traccar/database/NamedParameterStatement.java | 274 |
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); - } - } - } - } |