Skip to content

Commit ff8860f

Browse files
committed
Move mapUTCNano to DateTimeExtensions, Add initial Support for Primitive Types
1 parent 2f409aa commit ff8860f

6 files changed

Lines changed: 139 additions & 33 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package de.bytefish.jsqlserverbulkinsert.extensions;
2+
3+
import de.bytefish.jsqlserverbulkinsert.converters.BaseConverter;
4+
import de.bytefish.jsqlserverbulkinsert.converters.IConverter;
5+
import de.bytefish.jsqlserverbulkinsert.mapping.AbstractMapping;
6+
import de.bytefish.jsqlserverbulkinsert.util.TimestampUtils;
7+
8+
import java.sql.Date;
9+
import java.sql.Time;
10+
import java.sql.Timestamp;
11+
import java.sql.Types;
12+
import java.util.AbstractMap;
13+
import java.util.function.Function;
14+
15+
public class DateTimeExtensions {
16+
17+
public static <TEntity> void mapUTCNano(AbstractMapping<TEntity> mapping, String dateColumnName, String timeColumnName, Function<TEntity, Long> propertyGetter) {
18+
19+
mapping.mapProperty(dateColumnName, Types.DATE, propertyGetter, new BaseConverter<Long>() {
20+
@Override
21+
public Object internalConvert(Long value) {
22+
AbstractMap.SimpleImmutableEntry<Long, Integer> convertedDT = TimestampUtils.convertUtcNanoToEpochSecAndNano(value);
23+
24+
return new Date(convertedDT.getKey() * 1000);
25+
}
26+
});
27+
28+
mapping.mapProperty(timeColumnName, Types.TIME, propertyGetter, new BaseConverter<Long>() {
29+
@Override
30+
public Object internalConvert(Long value) {
31+
AbstractMap.SimpleImmutableEntry<Long, Integer> convertedDT = TimestampUtils.convertUtcNanoToEpochSecAndNano(value);
32+
Time t = new Time(convertedDT.getKey() * 1000);
33+
return t.toString() + "." + convertedDT.getValue() / 100; // send as string bc java.sql.Time supports only millisecond precision!?
34+
35+
}
36+
});
37+
}
38+
39+
public static <TEntity> void mapUTCNano(AbstractMapping<TEntity> mapping, String columnName, Function<TEntity, Long> propertyGetter) {
40+
41+
mapping.mapProperty(columnName, Types.TIMESTAMP, propertyGetter, new BaseConverter<Long>() {
42+
@Override
43+
public Object internalConvert(Long value) {
44+
45+
AbstractMap.SimpleImmutableEntry<Long, Integer> convertedDT = TimestampUtils.convertUtcNanoToEpochSecAndNano(value);
46+
47+
Timestamp castedResult = new Timestamp(convertedDT.getKey() * 1000);
48+
castedResult.setNanos(convertedDT.getValue());
49+
50+
return castedResult;
51+
}
52+
});
53+
}
54+
55+
56+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package de.bytefish.jsqlserverbulkinsert.functional;
2+
3+
@FunctionalInterface
4+
public interface ToBooleanFunction<T> {
5+
6+
/**
7+
* Applies this function to the given argument.
8+
*
9+
* @param value the function argument
10+
* @return the function result
11+
*/
12+
boolean applyAsBoolean(T value);
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package de.bytefish.jsqlserverbulkinsert.functional;
2+
3+
@FunctionalInterface
4+
public interface ToFloatFunction<T> {
5+
6+
/**
7+
* Applies this function to the given argument.
8+
*
9+
* @param value the function argument
10+
* @return the function result
11+
*/
12+
float applyAsFloat(T value);
13+
}

JSqlServerBulkInsert/src/main/java/de/bytefish/jsqlserverbulkinsert/mapping/AbstractMapping.java

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
package de.bytefish.jsqlserverbulkinsert.mapping;
55

66
import de.bytefish.jsqlserverbulkinsert.converters.*;
7-
import de.bytefish.jsqlserverbulkinsert.model.ColumnDefinition;
8-
import de.bytefish.jsqlserverbulkinsert.model.ColumnMetaData;
9-
import de.bytefish.jsqlserverbulkinsert.model.IColumnDefinition;
10-
import de.bytefish.jsqlserverbulkinsert.model.TableDefinition;
7+
import de.bytefish.jsqlserverbulkinsert.functional.ToBooleanFunction;
8+
import de.bytefish.jsqlserverbulkinsert.functional.ToFloatFunction;
9+
import de.bytefish.jsqlserverbulkinsert.model.*;
1110

1211
import java.math.BigDecimal;
1312
import java.math.BigInteger;
@@ -21,6 +20,7 @@
2120
import java.util.List;
2221
import java.util.Optional;
2322
import java.util.function.Function;
23+
import java.util.function.ToDoubleFunction;
2424
import java.util.function.ToIntFunction;
2525
import java.util.function.ToLongFunction;
2626

@@ -45,9 +45,9 @@ protected void mapBoolean(String columnName, Function<TEntity, Boolean> property
4545
mapProperty(columnName, Types.BIT, propertyGetter, new BooleanConverter());
4646
}
4747

48-
// protected void mapBoolean(String columnName, ToIntFunction<TEntity> propertyGetter) {
49-
// mapProperty(columnName, Types.BIT, (entity) -> (byte) propertyGetter.applyAsInt(entity), );
50-
// }
48+
protected void mapBoolean(String columnName, ToBooleanFunction<TEntity> propertyGetter) {
49+
mapProperty(columnName, Types.BIT, (entity) -> propertyGetter.applyAsBoolean(entity), new BooleanConverter());
50+
}
5151

5252
// region Text Functions
5353

@@ -92,10 +92,14 @@ protected void mapInteger(String columnName, Function<TEntity, Integer> property
9292
mapProperty(columnName, Types.INTEGER, 0, 0, isAutoIncrement, propertyGetter, new IntegerConverter());
9393
}
9494

95-
// protected void mapInteger(String columnName, ToIntFunction<TEntity> propertyGetter, boolean isAutoIncrement)
96-
// {
97-
// addColumn(columnName, Types.INTEGER, isAutoIncrement, (entity) -> propertyGetter.applyAsInt(entity));
98-
// }
95+
protected void mapInteger(String columnName, ToIntFunction<TEntity> propertyGetter)
96+
{
97+
mapProperty(columnName, Types.INTEGER, (entity) -> propertyGetter.applyAsInt(entity), new IntegerConverter());
98+
}
99+
100+
protected void mapInteger(String columnName, ToIntFunction<TEntity> propertyGetter, boolean isAutoIncrement) {
101+
mapProperty(columnName, Types.INTEGER, (entity) -> propertyGetter.applyAsInt(entity), new IntegerConverter());
102+
}
99103

100104
protected void mapLong(String columnName, Function<TEntity, Long> propertyGetter) {
101105
mapProperty(columnName, Types.BIGINT, propertyGetter, new LongConverter());
@@ -105,34 +109,42 @@ protected void mapLong(String columnName, Function<TEntity, Long> propertyGetter
105109
mapProperty(columnName, Types.BIGINT, 0, 0, isAutoIncrement, propertyGetter, new LongConverter());
106110
}
107111

108-
// protected void mapLong(String columnName, ToLongFunction<TEntity> propertyGetter, boolean isAutoIncrement) {
109-
// addColumn(columnName, Types.BIGINT, isAutoIncrement, (entity) -> propertyGetter.applyAsLong(entity));
110-
// }
112+
protected void mapLong(String columnName, ToLongFunction<TEntity> propertyGetter) {
113+
mapProperty(columnName, Types.BIGINT, (entity) -> propertyGetter.applyAsLong(entity), new LongConverter());
114+
}
115+
116+
protected void mapLong(String columnName, ToLongFunction<TEntity> propertyGetter, boolean isAutoIncrement) {
117+
mapProperty(columnName, Types.BIGINT, 0, 0, isAutoIncrement, (entity) -> propertyGetter.applyAsLong(entity), new LongConverter());
118+
}
111119

112120
protected void mapNumeric(String columnName, int precision, int scale, Function<TEntity, BigDecimal> propertyGetter) {
113121
mapProperty(columnName, Types.NUMERIC, precision, scale, false, propertyGetter, new BigDecimalConverter(scale));
114122
}
115123

116-
protected void mapDecimal(String columnName, int precision, int scale, Function<TEntity, BigDecimal> propertyGetter)
117-
{
124+
protected void mapDecimal(String columnName, int precision, int scale, Function<TEntity, BigDecimal> propertyGetter) {
118125
mapProperty(columnName, Types.DECIMAL, precision, scale, false, propertyGetter, new BigDecimalConverter(scale));
119126
}
120127

121-
protected void mapReal(String columnName, Function<TEntity, Float> propertyGetter)
122-
{
128+
protected void mapReal(String columnName, Function<TEntity, Float> propertyGetter) {
123129
mapProperty(columnName, Types.REAL, propertyGetter, new FloatConverter());
124130
}
125131

126-
protected void mapBigInt(String columnName, Function<TEntity, BigInteger> propertyGetter) {
132+
protected void mapReal(String columnName, ToFloatFunction<TEntity> propertyGetter) {
133+
mapProperty(columnName, Types.REAL, (entity) -> propertyGetter.applyAsFloat(entity), new FloatConverter());
134+
}
127135

136+
protected void mapBigInt(String columnName, Function<TEntity, BigInteger> propertyGetter) {
128137
mapProperty(columnName, Types.BIGINT, propertyGetter, new BigIntegerConverter());
129138
}
130139

131-
protected void mapDouble(String columnName, Function<TEntity, Double> propertyGetter)
132-
{
140+
protected void mapDouble(String columnName, Function<TEntity, Double> propertyGetter) {
133141
mapProperty(columnName, Types.DOUBLE, propertyGetter, new DoubleConverter());
134142
}
135143

144+
protected void mapDouble(String columnName, ToDoubleFunction<TEntity> propertyGetter) {
145+
mapProperty(columnName, Types.DOUBLE, (entity) -> propertyGetter.applyAsDouble(entity), new DoubleConverter());
146+
}
147+
136148
// endregion
137149

138150
// region Time Functions
@@ -153,6 +165,15 @@ protected void mapDateTime(String columnName, Function<TEntity, Timestamp> prope
153165
protected void mapLocalDateTime(String columnName, Function<TEntity, LocalDateTime> propertyGetter) {
154166
mapProperty(columnName, Types.TIMESTAMP, propertyGetter, new LocalDateTimeConverter());
155167
}
168+
169+
protected void mapTimeWithTimeZone(String columnName, Function<TEntity, OffsetTime> propertyGetter) {
170+
mapProperty(columnName, SqlServerTypes.TimeWithTimeZone, propertyGetter, new OffsetTimeConverter());
171+
}
172+
173+
protected void mapDateTimeWithTimeZone(String columnName, Function<TEntity, OffsetDateTime> propertyGetter) {
174+
mapProperty(columnName, SqlServerTypes.DateTimeWithTimeZone, propertyGetter, new OffsetDateTimeConverter());
175+
}
176+
156177
//
157178
// protected void mapUTCNano(String dateColumnName, String timeColumnName, Function<TEntity, Long> propertyGetter) {
158179
//
@@ -208,14 +229,6 @@ protected void mapLocalDateTime(String columnName, Function<TEntity, LocalDateTi
208229
// }
209230

210231

211-
protected void mapTimeWithTimeZone(String columnName, Function<TEntity, OffsetTime> propertyGetter) {
212-
mapProperty(columnName, 2013, propertyGetter, new OffsetTimeConverter());
213-
}
214-
215-
protected void mapDateTimeWithTimeZone(String columnName, Function<TEntity, OffsetDateTime> propertyGetter) {
216-
mapProperty(columnName, 2014, propertyGetter, new OffsetDateTimeConverter());
217-
}
218-
219232
// endregion
220233

221234
// region Binary
@@ -226,7 +239,7 @@ protected void mapVarBinary(String columnName, int maxLength, Function<TEntity,
226239

227240
// endregion
228241

229-
protected <TProperty> void mapProperty(String name, int type, Function<TEntity, TProperty> propertyGetter, IConverter<TProperty> converter)
242+
public <TProperty> void mapProperty(String name, int type, Function<TEntity, TProperty> propertyGetter, IConverter<TProperty> converter)
230243
{
231244
// Create the current Column Meta Data:
232245
ColumnMetaData columnMetaData = new ColumnMetaData(name, type);
@@ -235,7 +248,7 @@ protected <TProperty> void mapProperty(String name, int type, Function<TEntity,
235248
addColumn(columnMetaData, propertyGetter, converter);
236249
}
237250

238-
protected <TProperty> void mapProperty(String name, int type, int precision, int scale, boolean isAutoIncrement, Function<TEntity, TProperty> propertyGetter, IConverter<TProperty> converter)
251+
public <TProperty> void mapProperty(String name, int type, int precision, int scale, boolean isAutoIncrement, Function<TEntity, TProperty> propertyGetter, IConverter<TProperty> converter)
239252
{
240253
// Create the current Column Meta Data:
241254
ColumnMetaData columnMetaData = new ColumnMetaData(name, type, precision, scale, isAutoIncrement);
@@ -244,7 +257,7 @@ protected <TProperty> void mapProperty(String name, int type, int precision, int
244257
addColumn(columnMetaData, propertyGetter, converter);
245258
}
246259

247-
private <TProperty> void addColumn(ColumnMetaData columnMetaData, Function<TEntity, TProperty> propertyGetter, IConverter<TProperty> converter)
260+
public <TProperty> void addColumn(ColumnMetaData columnMetaData, Function<TEntity, TProperty> propertyGetter, IConverter<TProperty> converter)
248261
{
249262
// Add a new Column with the Meta Data and Property Getter:
250263
ColumnDefinition<TEntity, TProperty> columnDefinition = new ColumnDefinition<>(columnMetaData, propertyGetter, converter);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package de.bytefish.jsqlserverbulkinsert.model;
2+
3+
public class SqlServerTypes {
4+
5+
public static final int TimeWithTimeZone = 2013;
6+
7+
public static final int DateTimeWithTimeZone = 2014;
8+
9+
10+
}

JSqlServerBulkInsert/src/main/java/de/bytefish/jsqlserverbulkinsert/util/TimestampUtils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
import java.util.AbstractMap;
77

88
public class TimestampUtils {
9-
public AbstractMap.SimpleImmutableEntry<Long, Integer> convertUtcNanoToEpochSecAndNano(long value) {
9+
10+
public static AbstractMap.SimpleImmutableEntry<Long, Integer> convertUtcNanoToEpochSecAndNano(long value) {
1011
// loses subsecond data:
1112
long seconds = value / 1000000000;
1213
int nanoseconds = (int) (value - (seconds * 1000000000));

0 commit comments

Comments
 (0)