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}