sqlg3.runtime.RuntimeMapperImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sqlg3-runtime Show documentation
Show all versions of sqlg3-runtime Show documentation
SQLG is a preprocessor and a library that uses code generation to simplify writing JDBC code
package sqlg3.runtime;
import sqlg3.core.SQLGException;
import java.sql.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class RuntimeMapperImpl implements RuntimeMapper {
private final Map, TypeMapper>> mappers = new ConcurrentHashMap<>();
public final void register(TypeMapper mapper) {
mappers.put(mapper.cls, mapper);
}
/**
* Returns mapping for class {@code cls}
*
* @param cls class for which to define mapping
* @return mapping for the class {@code cls}
*/
@SuppressWarnings("unchecked")
@Override
public TypeMapper getMapper(Class cls) {
TypeMapper> mapper = mappers.get(cls);
if (mapper == null) {
throw new SQLGException("Cannot find mapping for class " + cls.getCanonicalName());
}
return (TypeMapper) mapper;
}
public interface PSSetter {
void set(PreparedStatement stmt, int index, T value) throws SQLException;
}
public interface RSGetter {
T get(ResultSet rs, int index) throws SQLException;
}
public interface CSGetter {
T get(CallableStatement cs, int index) throws SQLException;
}
public abstract static class AbstractBasicMapper extends TypeMapper {
private final int jdbcType;
private final PSSetter setter;
protected AbstractBasicMapper(Class cls, int jdbcType, PSSetter setter) {
super(cls);
this.jdbcType = jdbcType;
this.setter = setter;
}
@Override
public void set(PreparedStatement stmt, int index, T value) throws SQLException {
if (value == null) {
stmt.setNull(index, jdbcType);
} else {
setter.set(stmt, index, value);
}
}
@Override
public void register(CallableStatement cs, int index) throws SQLException {
cs.registerOutParameter(index, jdbcType);
}
}
public static final class BasicMapper extends AbstractBasicMapper {
private final RSGetter rsGetter;
private final CSGetter csGetter;
public BasicMapper(Class cls, int jdbcType, PSSetter setter, RSGetter rsGetter, CSGetter csGetter) {
super(cls, jdbcType, setter);
this.rsGetter = rsGetter;
this.csGetter = csGetter;
}
@Override
public T fetch(ResultSet rs, int index) throws SQLException {
return rsGetter.get(rs, index);
}
@Override
public T get(CallableStatement cs, int index) throws SQLException {
return csGetter.get(cs, index);
}
}
public static final class WrapperMapper extends AbstractBasicMapper {
private final RSGetter rsGetter;
private final CSGetter csGetter;
public WrapperMapper(Class cls, int jdbcType, PSSetter setter, RSGetter rsGetter, CSGetter csGetter) {
super(cls, jdbcType, setter);
this.rsGetter = rsGetter;
this.csGetter = csGetter;
}
@Override
public T fetch(ResultSet rs, int index) throws SQLException {
T value = rsGetter.get(rs, index);
if (rs.wasNull())
return null;
return value;
}
@Override
public T get(CallableStatement cs, int index) throws SQLException {
T value = csGetter.get(cs, index);
if (cs.wasNull())
return null;
return value;
}
}
public static final class EnumMapper> extends TypeMapper {
public EnumMapper(Class cls) {
super(cls);
}
private T convert(String name) {
return name == null ? null : Enum.valueOf(cls, name);
}
@Override
public T fetch(ResultSet rs, int index) throws SQLException {
String name = rs.getString(index);
return convert(name);
}
@Override
public void set(PreparedStatement stmt, int index, T value) throws SQLException {
stmt.setString(index, value == null ? null : value.name());
}
@Override
public void register(CallableStatement cs, int index) throws SQLException {
cs.registerOutParameter(index, Types.VARCHAR);
}
@Override
public T get(CallableStatement cs, int index) throws SQLException {
String name = cs.getString(index);
return convert(name);
}
}
public RuntimeMapperImpl() {
registerDefault();
}
public void registerDefault() {
register(new BasicMapper<>(
boolean.class, Types.BOOLEAN, PreparedStatement::setBoolean, ResultSet::getBoolean, CallableStatement::getBoolean
));
register(new WrapperMapper<>(
Boolean.class, Types.BOOLEAN, PreparedStatement::setBoolean, ResultSet::getBoolean, CallableStatement::getBoolean
));
register(new BasicMapper<>(
int.class, Types.INTEGER, PreparedStatement::setInt, ResultSet::getInt, CallableStatement::getInt
));
register(new WrapperMapper<>(
Integer.class, Types.INTEGER, PreparedStatement::setInt, ResultSet::getInt, CallableStatement::getInt
));
register(new BasicMapper<>(
long.class, Types.BIGINT, PreparedStatement::setLong, ResultSet::getLong, CallableStatement::getLong
));
register(new WrapperMapper<>(
Long.class, Types.BIGINT, PreparedStatement::setLong, ResultSet::getLong, CallableStatement::getLong
));
register(new BasicMapper<>(
double.class, Types.DOUBLE, PreparedStatement::setDouble, ResultSet::getDouble, CallableStatement::getDouble
));
register(new WrapperMapper<>(
Double.class, Types.DOUBLE, PreparedStatement::setDouble, ResultSet::getDouble, CallableStatement::getDouble
));
register(new BasicMapper<>(
String.class, Types.VARCHAR, PreparedStatement::setString, ResultSet::getString, CallableStatement::getString
));
register(new BasicMapper<>(
byte[].class, Types.VARBINARY, PreparedStatement::setBytes, ResultSet::getBytes, CallableStatement::getBytes
));
register(new BasicMapper<>(
Timestamp.class, Types.TIMESTAMP, PreparedStatement::setTimestamp, ResultSet::getTimestamp, CallableStatement::getTimestamp
));
register(new BasicMapper<>(
Date.class, Types.DATE, PreparedStatement::setDate, ResultSet::getDate, CallableStatement::getDate
));
register(new BasicMapper<>(
Time.class, Types.TIME, PreparedStatement::setTime, ResultSet::getTime, CallableStatement::getTime
));
}
}