| /******************************************************************************* |
| * Copyright (c) 2010 BSI Business Systems Integration AG. |
| * 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: |
| * BSI Business Systems Integration AG - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.scout.rt.server.services.common.jdbc.style; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.Reader; |
| import java.io.StringReader; |
| import java.lang.reflect.Array; |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| import java.sql.Blob; |
| import java.sql.CallableStatement; |
| import java.sql.Clob; |
| import java.sql.PreparedStatement; |
| import java.sql.ResultSet; |
| import java.sql.ResultSetMetaData; |
| import java.sql.SQLException; |
| import java.sql.Timestamp; |
| import java.sql.Types; |
| import java.text.SimpleDateFormat; |
| import java.util.Calendar; |
| import java.util.Collection; |
| import java.util.Date; |
| |
| import org.eclipse.scout.commons.IOUtility; |
| import org.eclipse.scout.commons.TriState; |
| import org.eclipse.scout.commons.TypeCastUtility; |
| import org.eclipse.scout.commons.holders.IHolder; |
| import org.eclipse.scout.commons.logger.IScoutLogger; |
| import org.eclipse.scout.commons.logger.ScoutLogManager; |
| import org.eclipse.scout.rt.server.services.common.jdbc.SqlBind; |
| |
| public abstract class AbstractSqlStyle implements ISqlStyle, ISqlStyle2 { |
| private static final long serialVersionUID = 1L; |
| private static final IScoutLogger LOG = ScoutLogManager.getLogger(AbstractSqlStyle.class); |
| |
| @Override |
| public String getConcatOp() { |
| return "||"; |
| } |
| |
| @Override |
| public String getLikeWildcard() { |
| return "%"; |
| } |
| |
| @Override |
| public String toLikePattern(Object value) { |
| String s = (value != null ? value.toString() : ""); |
| s = s.replace("*", getLikeWildcard()); |
| return s; |
| } |
| |
| @Override |
| public String toPlainText(Object value) { |
| if (value instanceof IHolder) { |
| value = ((IHolder) value).getValue(); |
| } |
| // |
| if (value == null) { |
| return "null"; |
| } |
| else if (value instanceof Boolean) { |
| Boolean b = (Boolean) value; |
| return b ? "1" : "0"; |
| } |
| else if (value instanceof TriState) { |
| TriState t = (TriState) value; |
| return "" + t.toString(); |
| } |
| else if (value instanceof String) { |
| String s = (String) value; |
| if (s.length() > MAX_SQL_STRING_LENGTH) { |
| s = s.substring(0, MAX_SQL_STRING_LENGTH); |
| LOG.warn("toPlainText of a String with more than " + MAX_SQL_STRING_LENGTH + " characters failed; truncated to '" + s + "'"); |
| return "'" + s.replaceAll("'", "''") + "'"; |
| } |
| return "'" + s.replaceAll("'", "''") + "'"; |
| } |
| else if (value instanceof char[]) { |
| if (((char[]) value).length > MAX_SQL_STRING_LENGTH) { |
| String s = new String((char[]) value, 0, MAX_SQL_STRING_LENGTH); |
| LOG.warn("toPlainText of a CLOB with more than " + MAX_SQL_STRING_LENGTH + " characters failed; truncated to '" + s + "'"); |
| return "'" + s.replaceAll("'", "''") + "'"; |
| } |
| String s = new String((char[]) value); |
| return "'" + s.replaceAll("'", "''") + "'"; |
| } |
| else if (value instanceof byte[]) { |
| LOG.warn("toPlainText of a BLOB failed; using NULL"); |
| return "NULL"; |
| } |
| else if (value instanceof Date) { |
| Date d = (Date) value; |
| SimpleDateFormat fmt = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); |
| return "to_date('" + fmt.format(d) + "','dd.mm.yyyy hh24:mi:ss')"; |
| } |
| else if (value instanceof Collection || value.getClass().isArray()) { |
| Object array; |
| if (value instanceof Collection) { |
| array = ((Collection) value).toArray(); |
| } |
| else { |
| array = value; |
| } |
| int n = Array.getLength(array); |
| StringBuffer buf = new StringBuffer(); |
| buf.append("("); |
| if (n > 0) { |
| for (int i = 0; i < n; i++) { |
| if (i > 0) { |
| buf.append(","); |
| } |
| buf.append(toPlainText(Array.get(array, i))); |
| } |
| } |
| else { |
| buf.append("-1"); |
| } |
| buf.append(")"); |
| return buf.toString(); |
| } |
| else { |
| return value.toString(); |
| } |
| } |
| |
| @Override |
| public String toAggregationAvg(String attribute) { |
| return "AVG(" + attribute + ")"; |
| } |
| |
| @Override |
| public String toAggregationCount(String attribute) { |
| return "COUNT(" + attribute + ")"; |
| } |
| |
| @Override |
| public String toAggregationMax(String attribute) { |
| return "MAX(" + attribute + ")"; |
| } |
| |
| @Override |
| public String toAggregationMedian(String attribute) { |
| return "MEDIAN(" + attribute + ")"; |
| } |
| |
| @Override |
| public String toAggregationMin(String attribute) { |
| return "MIN(" + attribute + ")"; |
| } |
| |
| @Override |
| public String toAggregationSum(String attribute) { |
| return "SUM(" + attribute + ")"; |
| } |
| |
| @Override |
| public SqlBind buildBindFor(Object o, Class nullType) { |
| if (o instanceof IHolder) { |
| IHolder h = (IHolder) o; |
| o = h.getValue(); |
| nullType = h.getHolderType(); |
| } |
| // |
| Class c; |
| if (o != null) { |
| c = o.getClass(); |
| } |
| else { |
| if (nullType != null && IHolder.class.isAssignableFrom(nullType)) { |
| try { |
| nullType = TypeCastUtility.getGenericsParameterClass(nullType, IHolder.class); |
| } |
| catch (Throwable t) { |
| nullType = null; |
| } |
| } |
| c = nullType; |
| } |
| // |
| if (o == null && c == null) { |
| return new SqlBind(Types.NULL, o); |
| } |
| // |
| if (Timestamp.class.isAssignableFrom(c)) { |
| return new SqlBind(Types.TIMESTAMP, o); |
| } |
| else if (java.sql.Date.class.isAssignableFrom(c)) { |
| return new SqlBind(Types.DATE, o); |
| } |
| else if (Calendar.class.isAssignableFrom(c)) { |
| if (o == null) { |
| return new SqlBind(Types.TIMESTAMP, o); |
| } |
| else { |
| return new SqlBind(Types.TIMESTAMP, new Timestamp(((Calendar) o).getTimeInMillis())); |
| } |
| } |
| else if (java.util.Date.class.isAssignableFrom(c)) { |
| if (o == null) { |
| return new SqlBind(Types.TIMESTAMP, o); |
| } |
| else { |
| return new SqlBind(Types.TIMESTAMP, new Timestamp(((Date) o).getTime())); |
| } |
| } |
| else if (Double.class.isAssignableFrom(c)) { |
| return new SqlBind(Types.DOUBLE, o); |
| } |
| else if (Float.class.isAssignableFrom(c)) { |
| return new SqlBind(Types.FLOAT, o); |
| } |
| else if (Integer.class.isAssignableFrom(c)) { |
| return new SqlBind(Types.INTEGER, o); |
| } |
| else if (Long.class.isAssignableFrom(c)) { |
| return new SqlBind(Types.BIGINT, o); |
| } |
| else if (BigInteger.class.isAssignableFrom(c)) { |
| return new SqlBind(Types.BIGINT, o); |
| } |
| else if (BigDecimal.class.isAssignableFrom(c)) { |
| return new SqlBind(Types.NUMERIC, o); |
| } |
| else if (Character.class.isAssignableFrom(c)) { |
| if (o == null) { |
| return new SqlBind(Types.VARCHAR, o); |
| } |
| else { |
| return new SqlBind(Types.VARCHAR, o.toString()); |
| } |
| } |
| else if (String.class.isAssignableFrom(c) || char[].class == c) { |
| if (o == null) { |
| return new SqlBind(Types.VARCHAR, o); |
| } |
| else { |
| String s; |
| boolean large; |
| if (String.class.isAssignableFrom(c)) { |
| s = (String) o; |
| large = isLargeString(s); |
| } |
| else { |
| // char[] binds are always treated as lobs |
| s = new String((char[]) o); |
| large = true; |
| } |
| if (large) { |
| if (isClobEnabled()) { |
| return new SqlBind(Types.CLOB, s); |
| } |
| else { |
| return new SqlBind(Types.LONGVARCHAR, s); |
| } |
| } |
| else { |
| return new SqlBind(Types.VARCHAR, s); |
| } |
| } |
| } |
| else if (byte[].class == c) { |
| if (o == null) { |
| if (isBlobEnabled()) { |
| return new SqlBind(Types.BLOB, o); |
| } |
| else { |
| return new SqlBind(Types.LONGVARBINARY, o); |
| } |
| } |
| else { |
| if (isBlobEnabled()) { |
| return new SqlBind(Types.BLOB, o); |
| } |
| else { |
| return new SqlBind(Types.LONGVARBINARY, o); |
| } |
| } |
| } |
| else if (Boolean.class.isAssignableFrom(c)) { |
| if (o == null) { |
| return new SqlBind(Types.INTEGER, null); |
| } |
| else { |
| return new SqlBind(Types.INTEGER, ((Boolean) o).booleanValue() ? 1 : 0); |
| } |
| } |
| else if (TriState.class.isAssignableFrom(c)) { |
| if (o == null) { |
| return new SqlBind(Types.INTEGER, null); |
| } |
| else { |
| return new SqlBind(Types.INTEGER, ((TriState) o).getIntegerValue()); |
| } |
| } |
| else if (Blob.class.isAssignableFrom(c)) { |
| return new SqlBind(Types.BLOB, o); |
| } |
| else if (Clob.class.isAssignableFrom(c)) { |
| return new SqlBind(Types.CLOB, o); |
| } |
| else if (c.isArray()) { |
| return new SqlBind(Types.ARRAY, o); |
| } |
| else { |
| if (o == null) { |
| return new SqlBind(Types.VARCHAR, o); |
| } |
| else { |
| throw new IllegalArgumentException("no SqlBind mapping for " + c); |
| } |
| } |
| } |
| |
| @Override |
| public void writeBind(PreparedStatement ps, int jdbcBindIndex, SqlBind bind) throws SQLException { |
| switch (bind.getSqlType()) { |
| case Types.NULL: { |
| try { |
| ps.setNull(jdbcBindIndex, Types.NULL); |
| |
| } |
| catch (SQLException e) { |
| ps.setNull(jdbcBindIndex, Types.VARCHAR); |
| } |
| break; |
| } |
| case Types.CLOB: { |
| if (bind.getValue() instanceof Clob || bind.getValue() == null) { |
| ps.setClob(jdbcBindIndex, (Clob) bind.getValue()); |
| } |
| else { |
| String s = (String) bind.getValue(); |
| ps.setCharacterStream(jdbcBindIndex, new StringReader(s), s.length()); |
| } |
| break; |
| } |
| case Types.BLOB: { |
| if (bind.getValue() instanceof Blob || bind.getValue() == null) { |
| ps.setBlob(jdbcBindIndex, (Blob) bind.getValue()); |
| } |
| else { |
| byte[] data = (byte[]) bind.getValue(); |
| ps.setBinaryStream(jdbcBindIndex, new ByteArrayInputStream(data), data.length); |
| } |
| break; |
| } |
| case Types.LONGVARCHAR: { |
| String s = (String) bind.getValue(); |
| if (s != null) { |
| ps.setCharacterStream(jdbcBindIndex, new StringReader(s), s.length()); |
| } |
| else { |
| ps.setNull(jdbcBindIndex, Types.LONGVARCHAR); |
| } |
| break; |
| } |
| case Types.LONGVARBINARY: { |
| byte[] data = (byte[]) bind.getValue(); |
| try { |
| // try using setBytes() |
| ps.setBytes(jdbcBindIndex, data); |
| } |
| catch (Throwable e1) { |
| try { |
| // try using byte stream |
| ps.setBinaryStream(jdbcBindIndex, new ByteArrayInputStream(data), data.length); |
| } |
| catch (SQLException e2) { |
| // send original exception |
| if (e1 instanceof SQLException) { |
| throw (SQLException) e1; |
| } |
| else { |
| throw new SQLException("failed setting bytes on jdbcBindIndex " + jdbcBindIndex); |
| } |
| } |
| } |
| break; |
| } |
| case Types.DECIMAL: |
| case Types.NUMERIC: { |
| if (bind.getValue() instanceof BigDecimal) { |
| int scale = ((BigDecimal) bind.getValue()).scale(); |
| ps.setObject(jdbcBindIndex, bind.getValue(), bind.getSqlType(), scale); |
| } |
| else { |
| writeDefaultBind(ps, jdbcBindIndex, bind); |
| } |
| break; |
| } |
| default: { |
| writeDefaultBind(ps, jdbcBindIndex, bind); |
| } |
| } |
| } |
| |
| private void writeDefaultBind(PreparedStatement ps, int jdbcBindIndex, SqlBind bind) throws SQLException { |
| ps.setObject(jdbcBindIndex, bind.getValue(), bind.getSqlType()); |
| } |
| |
| @Override |
| public Object readBind(ResultSet rs, ResultSetMetaData meta, int type, int jdbcBindIndex) throws SQLException { |
| Object o = null; |
| switch (type) { |
| // General Number |
| case Types.DECIMAL: |
| case Types.NUMERIC: { |
| o = getConfiguredDecimalConversionStrategy().convertDecimalType(rs.getBigDecimal(jdbcBindIndex)); |
| break; |
| } |
| // Long |
| case Types.BIT: |
| case Types.BIGINT: |
| case Types.SMALLINT: |
| case Types.INTEGER: |
| case Types.TINYINT: { |
| o = new Long(rs.getLong(jdbcBindIndex)); |
| break; |
| } |
| // Double |
| case Types.DOUBLE: |
| case Types.FLOAT: |
| case Types.REAL: { |
| o = new Double(rs.getDouble(jdbcBindIndex)); |
| break; |
| } |
| // String |
| case Types.VARCHAR: |
| case Types.CHAR: { |
| o = rs.getString(jdbcBindIndex); |
| break; |
| } |
| // Date |
| case Types.DATE: { |
| // Build 154: changed from getDate to getTimestamp() |
| // o=result.getDate(i+1); |
| o = rs.getTimestamp(jdbcBindIndex); |
| break; |
| } |
| case Types.TIME: { |
| o = rs.getTime(jdbcBindIndex); |
| break; |
| } |
| case Types.TIMESTAMP: { |
| o = rs.getTimestamp(jdbcBindIndex); |
| break; |
| } |
| // Raw |
| case Types.LONGVARCHAR: { |
| try { |
| o = rs.getString(jdbcBindIndex); |
| } |
| catch (SQLException e) { |
| throw e; |
| } |
| break; |
| } |
| case Types.LONGVARBINARY: |
| case Types.VARBINARY: |
| case Types.BINARY: { |
| o = rs.getBytes(jdbcBindIndex); |
| break; |
| } |
| case Types.CLOB: { |
| Clob c = rs.getClob(jdbcBindIndex); |
| if (c == null) { |
| o = null; |
| } |
| else { |
| try { |
| int len = (int) c.length(); |
| if (len > 0) { |
| // fast read |
| char[] ch = new char[len]; |
| Reader r = c.getCharacterStream(); |
| int processed = 0; |
| while (processed < len) { |
| processed += r.read(ch, processed, len - processed); |
| } |
| o = new String(ch); |
| } |
| else { |
| // dynamic read |
| o = IOUtility.getContent(c.getCharacterStream()); |
| } |
| } |
| catch (SQLException e) { |
| throw e; |
| } |
| catch (Exception e) { |
| SQLException sqe = new SQLException("read CLOB on column0=" + jdbcBindIndex); |
| sqe.initCause(e); |
| throw sqe; |
| } |
| } |
| break; |
| } |
| case Types.BLOB: { |
| Blob b = rs.getBlob(jdbcBindIndex); |
| if (b == null) { |
| o = null; |
| } |
| else { |
| o = b.getBytes(1, (int) b.length()); |
| } |
| break; |
| } |
| default: { |
| o = rs.getObject(jdbcBindIndex); |
| } |
| } |
| // set to null if necessary |
| if (rs.wasNull()) { |
| o = null; |
| } |
| return o; |
| } |
| |
| @Override |
| public void registerOutput(CallableStatement cs, int index, Class c) throws SQLException { |
| if (c == null) { |
| throw new SQLException("registering output index " + index + " with type null"); |
| } |
| int jdbcType = getJdbcType(c); |
| cs.registerOutParameter(index, jdbcType); |
| } |
| |
| protected int getJdbcType(Class c) { |
| int jdbcType; |
| if (Timestamp.class.isAssignableFrom(c)) { |
| jdbcType = Types.TIMESTAMP; |
| } |
| else if (java.sql.Date.class.isAssignableFrom(c)) { |
| jdbcType = Types.DATE; |
| } |
| else if (Calendar.class.isAssignableFrom(c)) { |
| jdbcType = Types.TIMESTAMP; |
| } |
| else if (java.util.Date.class.isAssignableFrom(c)) { |
| jdbcType = Types.TIMESTAMP; |
| } |
| else if (Double.class.isAssignableFrom(c)) { |
| jdbcType = Types.DOUBLE; |
| } |
| else if (Float.class.isAssignableFrom(c)) { |
| jdbcType = Types.FLOAT; |
| } |
| else if (Integer.class.isAssignableFrom(c)) { |
| jdbcType = Types.INTEGER; |
| } |
| else if (Long.class.isAssignableFrom(c)) { |
| jdbcType = Types.BIGINT; |
| } |
| else if (BigInteger.class.isAssignableFrom(c)) { |
| jdbcType = Types.BIGINT; |
| } |
| else if (BigDecimal.class.isAssignableFrom(c)) { |
| jdbcType = Types.NUMERIC; |
| } |
| else if (String.class.isAssignableFrom(c) || char[].class == c) { |
| jdbcType = Types.VARCHAR; |
| } |
| else if (byte[].class == c) { |
| if (isBlobEnabled()) { |
| jdbcType = Types.BLOB; |
| } |
| else { |
| jdbcType = Types.LONGVARBINARY; |
| } |
| } |
| else if (Boolean.class.isAssignableFrom(c)) { |
| jdbcType = Types.INTEGER; |
| } |
| else if (TriState.class.isAssignableFrom(c)) { |
| jdbcType = Types.INTEGER; |
| } |
| else if (Blob.class.isAssignableFrom(c)) { |
| jdbcType = Types.BLOB; |
| } |
| else if (Clob.class.isAssignableFrom(c)) { |
| jdbcType = Types.CLOB; |
| } |
| else if (c.isArray()) { |
| jdbcType = Types.ARRAY; |
| } |
| else { |
| jdbcType = Types.NUMERIC; |
| } |
| return jdbcType; |
| } |
| |
| @Override |
| public String createBetween(String attribute, String bindName1, String bindName2) { |
| return attribute + " BETWEEN " + adaptBindName(bindName1) + " AND " + adaptBindName(bindName2); |
| } |
| |
| @Override |
| public String createDateBetween(String attribute, String bindName1, String bindName2) { |
| return attribute + " BETWEEN TRUNC(" + adaptBindNameTimeDateOp(bindName1) + ") AND (TRUNC(" + adaptBindNameTimeDateOp(bindName2) + ")+(86399/86400)) "; |
| } |
| |
| @Override |
| public String createDateTimeBetween(String attribute, String bindName1, String bindName2) { |
| return attribute + " BETWEEN TRUNC(" + adaptBindNameTimeDateOp(bindName1) + ",'MI') AND (TRUNC(" + adaptBindNameTimeDateOp(bindName2) + ",'MI')+(59/86400)) "; |
| } |
| |
| @Override |
| public String createStartsWith(String attribute, String bindName) { |
| return "upper(" + attribute + ") like upper(" + adaptBindName(bindName) + "||'%')"; |
| } |
| |
| @Override |
| public String createNotStartsWith(String attribute, String bindName) { |
| return "upper(" + attribute + ") not like upper(" + adaptBindName(bindName) + "||'%')"; |
| } |
| |
| @Override |
| public String createEndsWith(String attribute, String bindName) { |
| return "upper(" + attribute + ") like upper('%'||" + adaptBindName(bindName) + ")"; |
| } |
| |
| @Override |
| public String createNotEndsWith(String attribute, String bindName) { |
| return "upper(" + attribute + ") not like upper('%'||" + adaptBindName(bindName) + ")"; |
| } |
| |
| @Override |
| public String createContains(String attribute, String bindName) { |
| return "upper(" + attribute + ") like upper('%'||" + adaptBindName(bindName) + "||'%')"; |
| } |
| |
| @Override |
| public String createNotContains(String attribute, String bindName) { |
| return "upper(" + attribute + ") not like upper('%'||" + adaptBindName(bindName) + "||'%')"; |
| } |
| |
| @Override |
| public String createLike(String attribute, String bindName) { |
| return "upper(" + attribute + ") like upper(" + adaptBindName(bindName) + ")"; |
| } |
| |
| @Override |
| public String createNotLike(String attribute, String bindName) { |
| return "upper(" + attribute + ") not like upper(" + adaptBindName(bindName) + ")"; |
| } |
| |
| @Override |
| public String createNull(String attribute) { |
| return attribute + " is null"; |
| } |
| |
| @Override |
| public String createNotNull(String attribute) { |
| return attribute + " is not null"; |
| } |
| |
| @Override |
| public String createNumberNull(String attribute) { |
| return "nvl(" + attribute + ",0)=0"; |
| } |
| |
| @Override |
| public String createNumberNotNull(String attribute) { |
| return "nvl(" + attribute + ",0)<>0"; |
| } |
| |
| @Override |
| public String createTextNull(String attribute) { |
| return "nvl(" + attribute + ",'0')='0'"; |
| } |
| |
| @Override |
| public String createTextNotNull(String attribute) { |
| return "nvl(" + attribute + ",'0')<>'0'"; |
| } |
| |
| @Override |
| public String createIn(String attribute, String bindName) { |
| return attribute + "=" + adaptBindName(bindName); |
| } |
| |
| @Override |
| public String createNotIn(String attribute, String bindName) { |
| return "NOT(" + attribute + "=" + adaptBindName(bindName) + ")"; |
| } |
| |
| @Override |
| public String createDateIsToday(String attribute) { |
| return attribute + ">=TRUNC(SYSDATE) AND " + attribute + "<TRUNC(SYSDATE+1)"; |
| } |
| |
| @Override |
| public String createDateIsInLastDays(String attribute, String bindName) { |
| return attribute + ">=TRUNC(SYSDATE-(" + adaptBindNameTimeDateOp(bindName) + ")) AND " + attribute + "<TRUNC(SYSDATE+1)"; |
| } |
| |
| @Override |
| public String createDateIsInNextDays(String attribute, String bindName) { |
| return attribute + ">=TRUNC(SYSDATE) AND " + attribute + "<TRUNC(SYSDATE+" + adaptBindNameTimeDateOp(bindName) + "+1)"; |
| } |
| |
| @Override |
| public String createDateIsInDays(String attribute, String bindName) { |
| return attribute + ">=TRUNC(SYSDATE+" + adaptBindNameTimeDateOp(bindName) + ") AND " + attribute + "<TRUNC(SYSDATE+" + adaptBindNameTimeDateOp(bindName) + "+1)"; |
| } |
| |
| @Override |
| public String createDateIsInWeeks(String attribute, String bindName) { |
| return attribute + ">=TRUNC(SYSDATE+((" + adaptBindNameTimeDateOp(bindName) + ")*7)) AND " + attribute + "<TRUNC(SYSDATE+((" + adaptBindNameTimeDateOp(bindName) + ")*7)+1)"; |
| } |
| |
| @Override |
| public String createDateIsInLastMonths(String attribute, String bindName) { |
| return attribute + ">=TRUNC(ADD_MONTHS(SYSDATE,(-1)*(" + adaptBindNameTimeDateOp(bindName) + "))) AND " + attribute + "<TRUNC(SYSDATE+1)"; |
| } |
| |
| @Override |
| public String createDateIsInNextMonths(String attribute, String bindName) { |
| return attribute + ">=TRUNC(SYSDATE) AND " + attribute + "<TRUNC(ADD_MONTHS(SYSDATE," + adaptBindNameTimeDateOp(bindName) + ")+1)"; |
| } |
| |
| @Override |
| public String createDateIsInMonths(String attribute, String bindName) { |
| return attribute + ">=TRUNC(ADD_MONTHS(SYSDATE," + adaptBindNameTimeDateOp(bindName) + ")) AND " + attribute + "<TRUNC(ADD_MONTHS(SYSDATE," + adaptBindNameTimeDateOp(bindName) + ")+1)"; |
| } |
| |
| @Override |
| public String createDateIsInLEDays(String attribute, String bindName) { |
| return attribute + "<TRUNC(SYSDATE+" + adaptBindNameTimeDateOp(bindName) + "+1)"; |
| } |
| |
| @Override |
| public String createDateIsInLEWeeks(String attribute, String bindName) { |
| return attribute + "<TRUNC(SYSDATE+((" + adaptBindNameTimeDateOp(bindName) + ")*7)+1)"; |
| } |
| |
| @Override |
| public String createDateIsInLEMonths(String attribute, String bindName) { |
| return attribute + "<TRUNC(ADD_MONTHS(SYSDATE," + adaptBindNameTimeDateOp(bindName) + ")+1)"; |
| } |
| |
| @Override |
| public String createDateIsInGEDays(String attribute, String bindName) { |
| return attribute + ">=TRUNC(SYSDATE+" + adaptBindNameTimeDateOp(bindName) + ")"; |
| } |
| |
| @Override |
| public String createDateIsInGEWeeks(String attribute, String bindName) { |
| return attribute + ">=TRUNC(SYSDATE+((" + adaptBindNameTimeDateOp(bindName) + ")*7))"; |
| } |
| |
| @Override |
| public String createDateIsInGEMonths(String attribute, String bindName) { |
| return attribute + ">=TRUNC(ADD_MONTHS(SYSDATE," + adaptBindNameTimeDateOp(bindName) + "))"; |
| } |
| |
| @Override |
| public String createDateIsNotToday(String attribute) { |
| return "(" + attribute + "<TRUNC(SYSDATE) OR " + attribute + ">=TRUNC(SYSDATE+1))"; |
| } |
| |
| @Override |
| public String createDateTimeIsNow(String attribute) { |
| return "(" + attribute + ">=TRUNC(SYSDATE, 'MI') AND " + attribute + "<(TRUNC(SYSDATE, 'MI')+(1/24/60)))"; |
| } |
| |
| @Override |
| public String createDateTimeIsInLEMinutes(String attribute, String bindName) { |
| return attribute + "<(TRUNC(SYSDATE, 'MI')+((" + adaptBindNameTimeDateOp(bindName) + "+1)/24/60))"; |
| } |
| |
| @Override |
| public String createDateTimeIsInLEHours(String attribute, String bindName) { |
| return attribute + "<(TRUNC(SYSDATE, 'MI')+((1/24/60)+(" + adaptBindNameTimeDateOp(bindName) + "/24)))"; |
| } |
| |
| @Override |
| public String createDateTimeIsInGEMinutes(String attribute, String bindName) { |
| return attribute + ">=(TRUNC(SYSDATE, 'MI')+(" + adaptBindNameTimeDateOp(bindName) + "/24/60))"; |
| } |
| |
| @Override |
| public String createDateTimeIsInGEHours(String attribute, String bindName) { |
| return attribute + ">=(TRUNC(SYSDATE, 'MI')+(" + adaptBindNameTimeDateOp(bindName) + "/24))"; |
| } |
| |
| @Override |
| public String createDateTimeIsNotNow(String attribute) { |
| return "(" + attribute + "<TRUNC(SYSDATE, 'MI') OR " + attribute + ">=(TRUNC(SYSDATE, 'MI')+(1/24/60)))"; |
| } |
| |
| @Override |
| public String createTimeIsNow(String attribute) { |
| return attribute + ">=((TO_CHAR(SYSDATE,'HH24')*60) + TO_CHAR(SYSDATE,'MI'))/24/60 AND " + attribute + "<((TO_CHAR(SYSDATE,'HH24')*60)+TO_CHAR(SYSDATE,'MI')+(1/24/60))/24/60"; |
| } |
| |
| @Override |
| public String createTimeIsNotNow(String attribute) { |
| return attribute + "<((TO_CHAR(SYSDATE,'HH24')*60) + TO_CHAR(SYSDATE,'MI'))/24/60 OR " + attribute + ">((TO_CHAR(SYSDATE,'HH24')*60)+TO_CHAR(SYSDATE,'MI')+(1/24/60))/24/60"; |
| } |
| |
| @Override |
| public String createTimeIsInMinutes(String attribute, String bindName) { |
| return attribute + ">=((TO_CHAR(SYSDATE,'HH24')*60) + TO_CHAR(SYSDATE,'MI')+(" + adaptBindNameTimeDateOp(bindName) + "/24/60))/24/60 AND " + attribute + "<((TO_CHAR(SYSDATE,'HH24')*60)+TO_CHAR(SYSDATE,'MI')+((" + adaptBindNameTimeDateOp(bindName) + "+1)/24/60))/24/60"; |
| } |
| |
| @Override |
| public String createTimeIsInHours(String attribute, String bindName) { |
| return attribute + ">=((TO_CHAR(SYSDATE,'HH24')*60) + TO_CHAR(SYSDATE,'MI')+(" + adaptBindNameTimeDateOp(bindName) + "/24))/24/60 AND " + attribute + "<((TO_CHAR(SYSDATE,'HH24')*60)+TO_CHAR(SYSDATE,'MI')+(" + adaptBindNameTimeDateOp(bindName) + "/24)+(1/24/60))/24/60"; |
| } |
| |
| @Override |
| public String createTimeIsInLEMinutes(String attribute, String bindName) { |
| return attribute + "<((TO_CHAR(SYSDATE,'HH24')*60) + TO_CHAR(SYSDATE,'MI')+((" + adaptBindNameTimeDateOp(bindName) + "+1)/24/60))/24/60"; |
| } |
| |
| @Override |
| public String createTimeIsInLEHours(String attribute, String bindName) { |
| return attribute + "<((TO_CHAR(SYSDATE,'HH24')*60) + TO_CHAR(SYSDATE,'MI')+(" + adaptBindNameTimeDateOp(bindName) + "/24)+(1/24/60))/24/60"; |
| } |
| |
| @Override |
| public String createTimeIsInGEMinutes(String attribute, String bindName) { |
| return attribute + ">=((TO_CHAR(SYSDATE,'HH24')*60) + TO_CHAR(SYSDATE,'MI')+(" + adaptBindNameTimeDateOp(bindName) + "/24/60))/24/60"; |
| } |
| |
| @Override |
| public String createTimeIsInGEHours(String attribute, String bindName) { |
| return attribute + ">=((TO_CHAR(SYSDATE,'HH24')*60) + TO_CHAR(SYSDATE,'MI')+(" + adaptBindNameTimeDateOp(bindName) + "/24))/24/60"; |
| } |
| |
| @Override |
| public String createEQ(String attribute, String bindName) { |
| return attribute + "=" + adaptBindName(bindName); |
| } |
| |
| @Override |
| public String createDateEQ(String attribute, String bindName) { |
| return attribute + "=TRUNC(" + adaptBindName(bindName) + ")"; |
| } |
| |
| @Override |
| public String createDateTimeEQ(String attribute, String bindName) { |
| return attribute + "=TRUNC(" + adaptBindNameTimeDateOp(bindName) + ",'MI')"; |
| } |
| |
| @Override |
| public String createGE(String attribute, String bindName) { |
| return attribute + ">=" + adaptBindName(bindName); |
| } |
| |
| @Override |
| public String createDateGE(String attribute, String bindName) { |
| return attribute + ">=TRUNC(" + adaptBindName(bindName) + ")"; |
| } |
| |
| @Override |
| public String createDateTimeGE(String attribute, String bindName) { |
| return attribute + ">=TRUNC(" + adaptBindNameTimeDateOp(bindName) + ",'MI')"; |
| } |
| |
| @Override |
| public String createGT(String attribute, String bindName) { |
| return attribute + ">" + adaptBindName(bindName); |
| } |
| |
| @Override |
| public String createDateGT(String attribute, String bindName) { |
| return attribute + ">TRUNC(" + adaptBindName(bindName) + ")"; |
| } |
| |
| @Override |
| public String createDateTimeGT(String attribute, String bindName) { |
| return attribute + ">TRUNC(" + adaptBindNameTimeDateOp(bindName) + ",'MI')"; |
| } |
| |
| @Override |
| public String createLE(String attribute, String bindName) { |
| return attribute + "<=" + adaptBindName(bindName); |
| } |
| |
| @Override |
| public String createDateLE(String attribute, String bindName) { |
| return attribute + "<=(TRUNC(" + adaptBindName(bindName) + ")+(86399/86400))"; |
| } |
| |
| @Override |
| public String createDateTimeLE(String attribute, String bindName) { |
| return attribute + "<=(TRUNC(" + adaptBindNameTimeDateOp(bindName) + ",'MI')+(59/86400))"; |
| } |
| |
| @Override |
| public String createLT(String attribute, String bindName) { |
| return attribute + "<" + adaptBindName(bindName); |
| } |
| |
| @Override |
| public String createDateLT(String attribute, String bindName) { |
| return attribute + "<TRUNC(" + adaptBindName(bindName) + ")"; |
| } |
| |
| @Override |
| public String createDateTimeLT(String attribute, String bindName) { |
| return attribute + "<TRUNC(" + adaptBindNameTimeDateOp(bindName) + ",'MI')"; |
| } |
| |
| @Override |
| public String createNEQ(String attribute, String bindName) { |
| return attribute + "<>" + adaptBindName(bindName); |
| } |
| |
| @Override |
| public String createDateNEQ(String attribute, String bindName) { |
| return attribute + "<>TRUNC(" + adaptBindName(bindName) + ")"; |
| } |
| |
| @Override |
| public String createDateTimeNEQ(String attribute, String bindName) { |
| return attribute + "<>TRUNC(" + adaptBindNameTimeDateOp(bindName) + ",'MI')"; |
| } |
| |
| protected abstract int getMaxListSize(); |
| |
| @Override |
| public String createInList(String attribute, Object array) { |
| Object[] values = toArray(array); |
| if (values.length == 0) { |
| return createNull(attribute); |
| } |
| int max = getMaxListSize(); |
| StringBuffer buf = new StringBuffer(); |
| buf.append("(");// bracket 1 |
| for (int i = 0; i < values.length; i = i + max) { |
| if (i > 0) { |
| buf.append(" OR "); |
| } |
| buf.append("(");// bracket 2 |
| buf.append(attribute); |
| buf.append(" IN "); |
| buf.append("(");// bracket 3 |
| for (int k = i; k < values.length && k < i + max; k++) { |
| if (k > i) { |
| buf.append(","); |
| } |
| buf.append(toPlainText(values[k])); |
| } |
| buf.append(")");// bracket 3 |
| buf.append(")");// bracket 2 |
| } |
| buf.append(")");// bracket 1 |
| return buf.toString(); |
| } |
| |
| @Override |
| public String createNotInList(String attribute, Object array) { |
| Object[] values = toArray(array); |
| if (values.length == 0) { |
| return createNotNull(attribute); |
| } |
| int max = getMaxListSize(); |
| StringBuffer buf = new StringBuffer(); |
| buf.append("(");// bracket 1 |
| for (int i = 0; i < values.length; i = i + max) { |
| if (i > 0) { |
| buf.append(" AND "); |
| } |
| buf.append("(");// bracket 2 |
| buf.append(attribute); |
| buf.append(" NOT IN "); |
| buf.append("(");// bracket 3 |
| for (int k = i; k < values.length && k < i + max; k++) { |
| if (k > i) { |
| buf.append(","); |
| } |
| buf.append(toPlainText(values[k])); |
| } |
| buf.append(")");// bracket 3 |
| buf.append(")");// bracket 2 |
| } |
| buf.append(")");// bracket 1 |
| return buf.toString(); |
| } |
| |
| @Override |
| public boolean isCreatingInListGeneratingBind(Object array) { |
| return false; |
| } |
| |
| @Override |
| public String getSysdateToken() { |
| return "SYSDATE"; |
| } |
| |
| @Override |
| public String getLowerToken() { |
| return "LOWER"; |
| } |
| |
| @Override |
| public String getUpperToken() { |
| return "UPPER"; |
| } |
| |
| @Override |
| public String getTrimToken() { |
| return "TRIM"; |
| } |
| |
| @Override |
| public String getNvlToken() { |
| return "NVL"; |
| } |
| |
| protected Object[] toArray(Object array) { |
| if (array == null) { |
| return new Object[0]; |
| } |
| if (!array.getClass().isArray()) { |
| return new Object[]{array}; |
| } |
| int len = Array.getLength(array); |
| Object[] a = new Object[len]; |
| for (int i = 0; i < a.length; i++) { |
| a[i] = Array.get(array, i); |
| } |
| return a; |
| } |
| |
| protected String adaptBindName(String bindName) { |
| if (bindName == null) { |
| return bindName; |
| } |
| if (bindName.startsWith(PLAIN_BIND_MARKER_PREFIX)) { |
| return bindName.substring(1); |
| } |
| return ":" + bindName; |
| } |
| |
| protected String adaptBindNameTimeDateOp(String bindName) { |
| return adaptBindName(bindName); |
| } |
| |
| @Override |
| public void commit() { |
| } |
| |
| @Override |
| public void rollback() { |
| } |
| |
| /** |
| * Gets the strategy to convert a decimal / numeric DB type into a data type in Java. |
| * <code>DecimalConversion.NONE</code> means that nothing is converted. <code>DecimalConversion.LEGACY</code> means |
| * that the old implementation (prior to Scout 3.10.0-M2) will be used: Numeric / decimal types without a scale are |
| * converted to <code>java.lang.Long</code>, with a scale they are converted to <code>java.lang.Double</code>. |
| * By default <code>DecimalConversion.NONE</code> will be returned. |
| * |
| * @since 3.10.0-M2 |
| * @return strategy for the decimal conversion |
| */ |
| protected DecimalConversion getConfiguredDecimalConversionStrategy() { |
| return DecimalConversion.NONE; |
| } |
| |
| /** |
| * @since 3.10.0-M2 |
| */ |
| public enum DecimalConversion { |
| NONE { |
| @Override |
| public Object convertDecimalType(BigDecimal bd) { |
| return bd; |
| } |
| }, |
| LEGACY { |
| @Override |
| public Object convertDecimalType(BigDecimal bd) { |
| if (bd == null) { |
| return null; |
| } |
| if (bd.scale() == 0) { |
| return bd.longValue(); |
| } |
| return bd.doubleValue(); |
| } |
| }; |
| |
| public abstract Object convertDecimalType(BigDecimal bd); |
| } |
| |
| } |