DialectBase.java
package com.github.mygreen.sqlmapper.core.dialect;
import java.util.HashMap;
import java.util.Map;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
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.where.metamodel.OperationHandler;
import com.github.mygreen.sqlmapper.metamodel.operator.Operator;
import lombok.Getter;
/**
* {@link Dialect}のベースとなるクラス。
* 多くのDBに共通する設定はこのクラスで実装し、異なる部分を継承先で実装します。
*
*
* @author T.TSUCHIE
*
*/
public abstract class DialectBase implements Dialect {
/**
* メタモデルによる各演算子の処理のマップ。
*/
@Getter
protected Map<Class<?>, OperationHandler<? extends Operator>> operationHandlerMap = new HashMap<>();
/**
* {@inheritDoc}
*
* @return {@link GenerationType#TABLE} を返します。
*/
@Override
public GenerationType getDefaultGenerationType() {
return GenerationType.TABLE;
}
@Override
public ValueType<?> getValueType(@Nullable ValueType<?> valueType) {
return valueType;
}
/**
* {@inheritDoc}
*
* @return {@literal "count(*)"} を返します。
*/
@Override
public String getCountSql() {
return "count(*)";
}
/**
* {@inheritDoc}
*
* @return {@literal "select count(*) from (<sql>)"} を返します。
*/
public String convertGetCountSql(final String sql) {
Assert.hasLength(sql, "sql should be not empty.");
return "select count(*) from ( " + sql + " )";
}
/**
* {@inheritDoc}
*
* @return 空文字({@literal ""})を返します。
*/
@Override
public String getHintComment(final String hint) {
return "";
}
/**
* {@inheritDoc}
*
* @return {@link SelectForUpdateType#NORMAL} を返します。
*/
@Override
public boolean supportsSelectForUpdate(final SelectForUpdateType type) {
return type == SelectForUpdateType.NORMAL;
}
/**
* {@inheritDoc}
*
* @return {@literal "for update"} を返します。
*/
@Override
public String getForUpdateSql(final SelectForUpdateType type, final int waitSeconds) {
return " for update";
}
/**
* {@inheritDoc}
*/
@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 (limit >= 0) {
buf.append(" limit ")
.append(limit);
}
if (offset >= 0) {
buf.append(" offset ")
.append(offset);
}
return buf.toString();
}
/**
* {@inheritDoc}
*
* @return {@literal false} を返します。
*/
@Override
public boolean needsParameterForResultSet() {
return false;
}
/**
* メタモデルに対する演算子に対する処理を登録します。
* <p>登録する際に、{@literal OperationHandler#init()}を実行します。
*
* @since 0.3
* @param <T> 演算子の種別
* @param operatorClass 演算子種別のクラス
* @param handler 演算子に対する処理
*/
public <T extends Operator> void register(Class<T> operatorClass, OperationHandler<T> handler) {
this.operationHandlerMap.put(operatorClass, handler);
}
}