OracleDialect.java
package com.github.mygreen.sqlmapper.core.dialect;
import javax.sql.DataSource;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer;
import org.springframework.lang.Nullable;
import com.github.mygreen.sqlmapper.core.annotation.GeneratedValue.GenerationType;
import com.github.mygreen.sqlmapper.core.query.SelectForUpdateType;
import com.github.mygreen.sqlmapper.core.type.ValueType;
import com.github.mygreen.sqlmapper.core.type.standard.BooleanType;
import com.github.mygreen.sqlmapper.core.type.standard.NumberableBooleanType;
/**
* Oracle v12+用の方言の定義。
*
* @version 0.3
* @author T.TSUCHIE
*
*/
public class OracleDialect extends DialectBase {
/**
* DB側が整数型のとき、Javaのboolean型にマッピングします。
*/
protected final NumberableBooleanType primitiveBooleanType = new NumberableBooleanType(true);
/**
* DB側が整数型のとき、JavaのラッパーのBoolean型にマッピングします。
*/
protected final NumberableBooleanType objectiveBooleanType = new NumberableBooleanType(false);
/**
* {@inheritDoc}
*
* @return {@literal "oracle"}を返します。
*/
@Override
public String getName() {
return "oracle";
}
/**
* {@inheritDoc}
*
* @return
* <ul>
* <li>{@link GenerationType#IDENTITY} : {@literal true}</li>
* <li>{@link GenerationType#SEQUENCE} : {@literal true}</li>
* <li>{@link GenerationType#TABLE} : {@literal true}</li>
* <li>{@link GenerationType#UUID} : {@literal true}</li>
* </ul>
*/
@Override
public boolean supportsGenerationType(GenerationType generationType) {
switch(generationType) {
case IDENTITY:
return true;
case SEQUENCE:
return true;
case TABLE:
return true;
case UUID:
return true;
default:
return false;
}
}
/**
* {@inheritDoc}
*
* @return {@link OracleSequenceMaxValueIncrementer} のインスタンスを返す。
*/
@Override
public DataFieldMaxValueIncrementer getSequenceIncrementer(DataSource dataSource, String sequenceName) {
return new OracleSequenceMaxValueIncrementer(dataSource, sequenceName);
}
/**
* {@inheritDoc}
*
* @return 与えられた値が {@literal boolean/Boolean}のとき、整数型に変換する {@link NumberableBooleanType} に変換します。
*/
@Override
public ValueType<?> getValueType(@Nullable ValueType<?> valueType) {
if(valueType == null) {
return null;
}
if(valueType instanceof BooleanType) {
if(((BooleanType)valueType).isForPrimitive()) {
return primitiveBooleanType;
} else {
return objectiveBooleanType;
}
}
return valueType;
}
/**
* {@inheritDoc}
*
* @return コメントの形式 /{@literal *}+ヒント{@literal *}/ の形式で返します。
*/
@Override
public String getHintComment(final String hint) {
return "/*+ " + hint + " */ ";
}
/**
* {@inheritDoc}
*
* @return {@literal OFFSET/FETCH} を使用して、LIMIT句を組み立てます。
* @throws IllegalArgumentException 引数{@literal offset} または {@literal limit} の値の何れかが 0より小さい場合にスローされます。
*/
@Override
public String convertLimitSql(String sql, int offset, int limit) {
if(offset < 0 && limit < 0) {
throw new IllegalArgumentException("Either offset or limit should be greather than 0.");
}
StringBuilder buf = new StringBuilder(sql.length() + 20);
buf.append(sql);
if(offset >= 0) {
buf.append(" offset ")
.append(offset)
.append(" rows");
}
if(limit >= 0) {
buf.append(" fetch first ")
.append(limit)
.append(" rows only");
}
return buf.toString();
}
/**
* {@inheritDoc}
*
* @return 必ず{@literal true} を返します。
*/
@Override
public boolean supportsSelectForUpdate(final SelectForUpdateType type) {
// 全てのタイプをサポートする
return true;
}
/**
* {@inheritDoc}
*
* @return
* <ul>
* <li>{@link SelectForUpdateType#NORMAL} : {@literal for update}</li>
* <li>{@link SelectForUpdateType#NOWAIT} : {@literal for update nowait}</li>
* <li>{@link SelectForUpdateType#WAIT} : {@literal for update wait <waitSeconds>}</li>
* </ul>
*/
@Override
public String getForUpdateSql(final SelectForUpdateType type, final int waitSeconds) {
StringBuilder buf = new StringBuilder(20)
.append(" for update");
switch(type) {
case NORMAL:
break;
case NOWAIT:
buf.append(" nowait");
break;
case WAIT:
buf.append(" wait ").append(waitSeconds);
break;
}
return buf.toString();
}
/**
* {@inheritDoc}
*
* @return {@literal true} を返します。
*/
@Override
public boolean needsParameterForResultSet() {
return true;
}
}