001// Licensed under the MIT license. See LICENSE file in the project root for full license information.
002
003package de.bytefish.pgbulkinsert.pgsql.handlers;
004
005import de.bytefish.pgbulkinsert.exceptions.ValueHandlerAlreadyRegisteredException;
006import de.bytefish.pgbulkinsert.exceptions.ValueHandlerNotRegisteredException;
007import de.bytefish.pgbulkinsert.pgsql.constants.DataType;
008import de.bytefish.pgbulkinsert.pgsql.handlers.utils.IntervalValueHandler;
009
010import java.util.EnumMap;
011import java.util.Map;
012import java.util.stream.Collectors;
013
014public class ValueHandlerProvider implements IValueHandlerProvider {
015
016    private final Map<DataType, IValueHandler> valueHandlers;
017
018    public ValueHandlerProvider() {
019        valueHandlers = new EnumMap<>(DataType.class);
020
021        add(DataType.Boolean, new BooleanValueHandler());
022        add(DataType.Char, new ByteValueHandler<>());
023        add(DataType.Numeric, new BigDecimalValueHandler<>());
024        add(DataType.DoublePrecision, new DoubleValueHandler<>());
025        add(DataType.SinglePrecision, new FloatValueHandler<>());
026        add(DataType.Date, new LocalDateValueHandler());
027        add(DataType.Time, new LocalTimeValueHandler());
028        add(DataType.Timestamp, new LocalDateTimeValueHandler());
029        add(DataType.TimestampTz, new ZonedDateTimeValueHandler());
030        add(DataType.Int2, new ShortValueHandler<>());
031        add(DataType.Int4, new IntegerValueHandler<>());
032        add(DataType.Int8, new LongValueHandler<>());
033        add(DataType.Text, new StringValueHandler());
034        add(DataType.VarChar, new StringValueHandler());
035        add(DataType.Inet4, new Inet4AddressValueHandler());
036        add(DataType.Inet6, new Inet6AddressValueHandler());
037        add(DataType.Uuid, new UUIDValueHandler());
038        add(DataType.Bytea, new ByteArrayValueHandler());
039        add(DataType.Jsonb, new JsonbValueHandler());
040        add(DataType.Hstore, new HstoreValueHandler());
041        add(DataType.Point, new PointValueHandler());
042        add(DataType.Box, new BoxValueHandler());
043        add(DataType.Line, new LineValueHandler());
044        add(DataType.LineSegment, new LineSegmentValueHandler());
045        add(DataType.Path, new PathValueHandler());
046        add(DataType.Polygon, new PolygonValueHandler());
047        add(DataType.Circle, new CircleValueHandler());
048        add(DataType.MacAddress, new MacAddressValueHandler());
049        add(DataType.TsRange, new RangeValueHandler<>(new LocalDateTimeValueHandler()));
050        add(DataType.TsTzRange, new RangeValueHandler<>(new ZonedDateTimeValueHandler()));
051        add(DataType.Int4Range, new RangeValueHandler<>(new IntegerValueHandler<>()));
052        add(DataType.Int8Range, new RangeValueHandler<>(new LongValueHandler<>()));
053        add(DataType.NumRange, new RangeValueHandler<>(new BigDecimalValueHandler<>()));
054        add(DataType.DateRange, new RangeValueHandler<>(new LocalDateValueHandler()));
055        add(DataType.Interval, new IntervalValueHandler());
056    }
057
058    public <TTargetType> ValueHandlerProvider add(DataType targetType, IValueHandler<TTargetType> valueHandler) {
059        if(valueHandlers.containsKey(targetType)) {
060            throw new ValueHandlerAlreadyRegisteredException(String.format("TargetType '%s' has already been registered", targetType));
061        }
062
063        valueHandlers.put(targetType, valueHandler);
064
065        return this;
066    }
067
068    @Override
069    public <TTargetType> IValueHandler<TTargetType> resolve(DataType dataType) {
070        
071        @SuppressWarnings("unchecked")
072                IValueHandler<TTargetType> handler = valueHandlers.get(dataType);
073        if(handler == null) {
074            throw new ValueHandlerNotRegisteredException(String.format("DataType '%s' has not been registered", dataType));
075        }
076        return handler;
077    }
078
079
080    @Override
081    public String toString() {
082
083        String valueHandlersString =
084                valueHandlers.entrySet()
085                        .stream()
086                        .map(e -> e.getValue().toString())
087                        .collect(Collectors.joining(", "));
088
089        return "ValueHandlerProvider{" +
090                "valueHandlers=[" + valueHandlersString + "]" +
091                '}';
092    }
093}