OracleDialect.java

  1. package com.github.mygreen.sqlmapper.core.dialect;

  2. import javax.sql.DataSource;

  3. import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
  4. import org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer;
  5. import org.springframework.lang.Nullable;

  6. import com.github.mygreen.sqlmapper.core.annotation.GeneratedValue.GenerationType;
  7. import com.github.mygreen.sqlmapper.core.query.SelectForUpdateType;
  8. import com.github.mygreen.sqlmapper.core.type.ValueType;
  9. import com.github.mygreen.sqlmapper.core.type.standard.BooleanType;
  10. import com.github.mygreen.sqlmapper.core.type.standard.NumberableBooleanType;

  11. /**
  12.  * Oracle v12+用の方言の定義。
  13.  *
  14.  * @version 0.3
  15.  * @author T.TSUCHIE
  16.  *
  17.  */
  18. public class OracleDialect extends DialectBase {

  19.     /**
  20.      * DB側が整数型のとき、Javaのboolean型にマッピングします。
  21.      */
  22.     protected final NumberableBooleanType primitiveBooleanType = new NumberableBooleanType(true);

  23.     /**
  24.      * DB側が整数型のとき、JavaのラッパーのBoolean型にマッピングします。
  25.      */
  26.     protected final NumberableBooleanType objectiveBooleanType = new NumberableBooleanType(false);

  27.     /**
  28.      * {@inheritDoc}
  29.      *
  30.      * @return {@literal "oracle"}を返します。
  31.      */
  32.     @Override
  33.     public String getName() {
  34.         return "oracle";
  35.     }

  36.     /**
  37.      * {@inheritDoc}
  38.      *
  39.      * @return
  40.      * <ul>
  41.      *  <li>{@link GenerationType#IDENTITY} : {@literal true}</li>
  42.      *  <li>{@link GenerationType#SEQUENCE} : {@literal true}</li>
  43.      *  <li>{@link GenerationType#TABLE} : {@literal true}</li>
  44.      *  <li>{@link GenerationType#UUID} : {@literal true}</li>
  45.      * </ul>
  46.      */
  47.     @Override
  48.     public boolean supportsGenerationType(GenerationType generationType) {
  49.         switch(generationType) {
  50.             case IDENTITY:
  51.                 return true;
  52.             case SEQUENCE:
  53.                 return true;
  54.             case TABLE:
  55.                 return true;
  56.             case UUID:
  57.                 return true;
  58.             default:
  59.                 return false;
  60.         }
  61.     }

  62.     /**
  63.      * {@inheritDoc}
  64.      *
  65.      * @return {@link OracleSequenceMaxValueIncrementer} のインスタンスを返す。
  66.      */
  67.     @Override
  68.     public DataFieldMaxValueIncrementer getSequenceIncrementer(DataSource dataSource, String sequenceName) {
  69.         return new OracleSequenceMaxValueIncrementer(dataSource, sequenceName);
  70.     }

  71.     /**
  72.      * {@inheritDoc}
  73.      *
  74.      * @return 与えられた値が {@literal boolean/Boolean}のとき、整数型に変換する {@link NumberableBooleanType} に変換します。
  75.      */
  76.     @Override
  77.     public ValueType<?> getValueType(@Nullable ValueType<?> valueType) {
  78.         if(valueType == null) {
  79.             return null;
  80.         }

  81.         if(valueType instanceof BooleanType) {
  82.             if(((BooleanType)valueType).isForPrimitive()) {
  83.                 return primitiveBooleanType;
  84.             } else {
  85.                 return objectiveBooleanType;
  86.             }
  87.         }
  88.         return valueType;
  89.     }

  90.     /**
  91.      * {@inheritDoc}
  92.      *
  93.      * @return コメントの形式 /{@literal *}+ヒント{@literal *}/ の形式で返します。
  94.      */
  95.     @Override
  96.     public String getHintComment(final String hint) {
  97.         return "/*+ " + hint + " */ ";
  98.     }

  99.     /**
  100.      * {@inheritDoc}
  101.      *
  102.      * @return {@literal OFFSET/FETCH} を使用して、LIMIT句を組み立てます。
  103.      * @throws IllegalArgumentException 引数{@literal offset} または {@literal limit} の値の何れかが 0より小さい場合にスローされます。
  104.      */
  105.     @Override
  106.     public String convertLimitSql(String sql, int offset, int limit) {

  107.         if(offset < 0 && limit < 0) {
  108.             throw new IllegalArgumentException("Either offset or limit should be greather than 0.");
  109.         }

  110.         StringBuilder buf = new StringBuilder(sql.length() + 20);
  111.         buf.append(sql);

  112.         if(offset >= 0) {
  113.             buf.append(" offset ")
  114.                 .append(offset)
  115.                 .append(" rows");

  116.         }

  117.         if(limit >= 0) {
  118.             buf.append(" fetch first ")
  119.                 .append(limit)
  120.                 .append(" rows only");
  121.         }

  122.         return buf.toString();

  123.     }

  124.     /**
  125.      * {@inheritDoc}
  126.      *
  127.      * @return 必ず{@literal true} を返します。
  128.      */
  129.     @Override
  130.     public boolean supportsSelectForUpdate(final SelectForUpdateType type) {
  131.         // 全てのタイプをサポートする
  132.         return true;
  133.     }

  134.     /**
  135.      * {@inheritDoc}
  136.      *
  137.      * @return
  138.      * <ul>
  139.      *   <li>{@link SelectForUpdateType#NORMAL} : {@literal for update}</li>
  140.      *   <li>{@link SelectForUpdateType#NOWAIT} : {@literal for update nowait}</li>
  141.      *   <li>{@link SelectForUpdateType#WAIT} : {@literal for update wait <waitSeconds>}</li>
  142.      * </ul>
  143.      */
  144.     @Override
  145.     public String getForUpdateSql(final SelectForUpdateType type, final int waitSeconds) {

  146.         StringBuilder buf = new StringBuilder(20)
  147.                 .append(" for update");

  148.         switch(type) {
  149.             case NORMAL:
  150.                 break;
  151.             case NOWAIT:
  152.                 buf.append(" nowait");
  153.                 break;
  154.             case WAIT:
  155.                 buf.append(" wait ").append(waitSeconds);
  156.                 break;
  157.         }

  158.         return buf.toString();
  159.     }

  160.     /**
  161.      * {@inheritDoc}
  162.      *
  163.      * @return {@literal true} を返します。
  164.      */
  165.     @Override
  166.     public boolean needsParameterForResultSet() {
  167.         return true;
  168.     }
  169. }