diff options
Diffstat (limited to 'sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlQuery.java')
-rw-r--r-- | sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlQuery.java | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlQuery.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlQuery.java new file mode 100644 index 0000000..b50b56e --- /dev/null +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlQuery.java @@ -0,0 +1,249 @@ +package io.trygvis.persistence.sql; + +import javax.persistence.FlushModeType; +import javax.persistence.LockModeType; +import javax.persistence.NoResultException; +import javax.persistence.NonUniqueResultException; +import javax.persistence.Parameter; +import javax.persistence.PersistenceException; +import javax.persistence.TemporalType; +import javax.persistence.TypedQuery; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static java.util.Collections.emptyMap; + +public class SqlQuery<T> implements TypedQuery<T> { + private final FromResultSet<T> fromResultSet; + private final SqlExecutor executor; + private final String sql; + + private final boolean isSqlFinal; + private int maxResults = -1; + private int firstResult = -1; + + public SqlQuery(FromResultSet<T> fromResultSet, SqlExecutor executor, String sql, boolean sqlFinal) { + this.fromResultSet = fromResultSet; + this.executor = executor; + this.sql = sql; + this.isSqlFinal = sqlFinal; + } + + @Override + public List<T> getResultList() { + return getResultList(firstResult, maxResults); + } + + @Override + public T getSingleResult() { + List<T> list = getResultList(0, 2); + if (list.size() == 1) { + return list.get(0); + } + + if (list.size() == 0) { + throw new NoResultException(); + } + + throw new NonUniqueResultException(); + } + + public List<T> getResultList(int offset, int limit) { + final String sql = generateSql(this.sql, offset, limit); + return executor.executeQuery(new SqlExecutor.QueryCommand<T>() { + @Override + public List<T> run(Connection c) throws SQLException { + List<T> list = new ArrayList<>(); + try (Statement stmt = c.createStatement()) { + ResultSet rs = stmt.executeQuery(sql); + while (rs.next()) { + T t = fromResultSet.fromResultSet(rs); + list.add(t); + } + } + return list; + } + }); + } + + private static String generateSql(String sql, int offset, int limit) { + if (offset > 0) { + sql += " OFFSET " + offset; + } + if (limit > 0) { + sql += " LIMIT " + limit; + } + + return sql; + } + + @Override + public int executeUpdate() { + return executor.executeUpdate(new SqlExecutor.UpdateCommand() { + @Override + public int run(Connection c) throws SQLException { + try (Statement stmt = c.createStatement()) { + return stmt.executeUpdate(sql); + } + } + }); + } + + @Override + public SqlQuery<T> setMaxResults(int maxResult) { + if (maxResult <= 0) { + throw new IllegalArgumentException("maxResult has to be positive: " + maxResult); + } + this.maxResults = maxResult; + return this; + } + + @Override + public int getMaxResults() { + return maxResults; + } + + @Override + public SqlQuery<T> setFirstResult(int startPosition) { + this.firstResult = startPosition; + return this; + } + + @Override + public int getFirstResult() { + return firstResult; + } + + @Override + public SqlQuery<T> setHint(String hintName, Object value) { + return null; + } + + @Override + public Map<String, Object> getHints() { + return emptyMap(); + } + + @Override + public <A> SqlQuery<T> setParameter(Parameter<A> param, A value) { + throw new UnsupportedOperationException(); + } + + @Override + public SqlQuery<T> setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public SqlQuery<T> setParameter(Parameter<Date> param, Date value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public SqlQuery<T> setParameter(String name, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public SqlQuery<T> setParameter(String name, Calendar value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public SqlQuery<T> setParameter(String name, Date value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public SqlQuery<T> setParameter(int position, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public SqlQuery<T> setParameter(int position, Calendar value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public SqlQuery<T> setParameter(int position, Date value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public Set<Parameter<?>> getParameters() { + throw new UnsupportedOperationException(); + } + + @Override + public Parameter<?> getParameter(String name) { + throw new UnsupportedOperationException(); + } + + @Override + public <T> Parameter<T> getParameter(String name, Class<T> type) { + throw new UnsupportedOperationException(); + } + + @Override + public Parameter<?> getParameter(int position) { + throw new UnsupportedOperationException(); + } + + @Override + public <T> Parameter<T> getParameter(int position, Class<T> type) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isBound(Parameter<?> param) { + throw new UnsupportedOperationException(); + } + + @Override + public <T> T getParameterValue(Parameter<T> param) { + throw new UnsupportedOperationException(); + } + + @Override + public Object getParameterValue(String name) { + throw new UnsupportedOperationException(); + } + + @Override + public Object getParameterValue(int position) { + throw new UnsupportedOperationException(); + } + + @Override + public SqlQuery<T> setFlushMode(FlushModeType flushMode) { + throw new UnsupportedOperationException(); + } + + @Override + public FlushModeType getFlushMode() { + throw new UnsupportedOperationException(); + } + + @Override + public SqlQuery<T> setLockMode(LockModeType lockMode) { + throw new UnsupportedOperationException(); + } + + @Override + public LockModeType getLockMode() { + throw new UnsupportedOperationException(); + } + + @Override + public <T> T unwrap(Class<T> klass) { + throw new PersistenceException("Unsupported class: " + klass); + } +} |