All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sqlg3.runtime.RuntimeMapperImpl Maven / Gradle / Ivy

Go to download

SQLG is a preprocessor and a library that uses code generation to simplify writing JDBC code

There is a newer version: 3.1
Show newest version
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
        ));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy