Skip to content

Commit c021d6b

Browse files
committed
Doris support deducing partitions
#149
1 parent c8238fb commit c021d6b

File tree

5 files changed

+110
-19
lines changed

5 files changed

+110
-19
lines changed

bitsail-common/src/main/java/com/bytedance/bitsail/common/util/DateUtil.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,7 @@
2626
import java.sql.Timestamp;
2727
import java.text.ParseException;
2828
import java.text.SimpleDateFormat;
29-
import java.util.Calendar;
30-
import java.util.Date;
31-
import java.util.HashMap;
32-
import java.util.Map;
33-
import java.util.TimeZone;
29+
import java.util.*;
3430

3531
public class DateUtil {
3632
public static final int LENGTH_SECOND = 10;
@@ -249,4 +245,25 @@ public static long convertStringToSeconds(Column column) {
249245
return stringToDate(column.asString(), null, null).toInstant().getEpochSecond();
250246
}
251247
}
248+
249+
public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
250+
List<Date> dataRange = new ArrayList<>();
251+
dataRange.add(beginDate);
252+
Calendar cal = Calendar.getInstance();
253+
cal.setTime(beginDate);
254+
while (endDate.after(cal.getTime())) {
255+
cal.add(Calendar.DAY_OF_MONTH, 1);
256+
dataRange.add(cal.getTime());
257+
}
258+
return dataRange;
259+
}
260+
261+
public static Date getNDaysAfterDate(Date date, int n){
262+
Calendar cal = Calendar.getInstance();
263+
cal.setTime(date);
264+
cal.add(Calendar.DAY_OF_MONTH, n);
265+
return cal.getTime();
266+
}
267+
268+
252269
}

bitsail-common/src/test/java/com/bytedance/bitsail/common/util/DateUtilTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
import org.junit.Assert;
2222
import org.junit.Test;
2323

24+
import java.text.ParseException;
25+
import java.text.SimpleDateFormat;
26+
import java.util.Date;
27+
2428
public class DateUtilTest {
2529
@Test
2630
public void testConvertStringToSeconds() {
@@ -29,4 +33,26 @@ public void testConvertStringToSeconds() {
2933
Assert.assertEquals(1575734400L, DateUtil.convertStringToSeconds(new StringColumn("2020-08-01")));
3034
Assert.assertEquals(1596214923L, DateUtil.convertStringToSeconds(new StringColumn("2020-08-01 01:02:03")));
3135
}
36+
37+
@Test
38+
public void testGetDatesBetweenTwoDate(){
39+
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
40+
try {
41+
Date dStart = sdf.parse("2022-12-26");
42+
Date dEnd = sdf.parse("2022-12-26");
43+
Assert.assertEquals(1, DateUtil.getDatesBetweenTwoDate(dStart, dEnd).size());
44+
} catch (ParseException e) {
45+
e.printStackTrace();
46+
}
47+
}
48+
@Test
49+
public void testGetNDaysAfterDate(){
50+
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
51+
try {
52+
Date date = sdf.parse("2022-12-31");
53+
Assert.assertEquals("2023-01-01", sdf.format(DateUtil.getNDaysAfterDate(date, 1)));
54+
} catch (ParseException e) {
55+
e.printStackTrace();
56+
}
57+
}
3258
}

bitsail-connectors/connector-doris/src/main/java/com/bytedance/bitsail/connector/doris/option/DorisWriterOptions.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
import com.bytedance.bitsail.common.option.WriterOptions;
2222

2323
import com.alibaba.fastjson.TypeReference;
24+
import com.bytedance.bitsail.connector.doris.partition.DorisPartitionTemplate;
2425

25-
import java.util.List;
2626
import java.util.Map;
2727

2828
import static com.bytedance.bitsail.common.option.ConfigOptions.key;
@@ -64,9 +64,9 @@ public interface DorisWriterOptions extends WriterOptions.BaseWriterOptions {
6464
key(WRITER_PREFIX + "table_has_partition")
6565
.defaultValue(true);
6666

67-
ConfigOption<List<Map<String, Object>>> PARTITIONS =
67+
ConfigOption<DorisPartitionTemplate> PARTITIONS =
6868
key(WRITER_PREFIX + "partitions")
69-
.onlyReference(new TypeReference<List<Map<String, Object>>>() {});
69+
.onlyReference(new TypeReference<DorisPartitionTemplate>() {});
7070

7171
ConfigOption<Integer> SINK_FLUSH_INTERVAL_MS =
7272
key(WRITER_PREFIX + "sink_flush_interval_ms")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.bytedance.bitsail.connector.doris.partition;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
9+
@AllArgsConstructor
10+
@NoArgsConstructor
11+
@Data
12+
public class DorisPartitionTemplate {
13+
14+
@JsonProperty(value = "prefix", required = false, defaultValue = "p")
15+
private String prefix;
16+
17+
@JsonProperty(value = "start_range", required = true)
18+
private String startRange;
19+
20+
@JsonProperty(value = "end_range", required = true)
21+
private String endRange;
22+
23+
@JsonProperty(value = "pattern", required = false, defaultValue = "yyyy-MM-dd")
24+
private String pattern;
25+
}

bitsail-connectors/connector-doris/src/main/java/com/bytedance/bitsail/connector/doris/sink/DorisSink.java

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
import com.bytedance.bitsail.base.connector.writer.v1.WriterCommitter;
2222
import com.bytedance.bitsail.base.serializer.BinarySerializer;
2323
import com.bytedance.bitsail.base.serializer.SimpleBinarySerializer;
24+
import com.bytedance.bitsail.common.BitSailException;
2425
import com.bytedance.bitsail.common.configuration.BitSailConfiguration;
2526
import com.bytedance.bitsail.common.exception.CommonErrorCode;
2627
import com.bytedance.bitsail.common.model.ColumnInfo;
2728
import com.bytedance.bitsail.common.type.TypeInfoConverter;
2829
import com.bytedance.bitsail.common.type.filemapping.FileMappingTypeInfoConverter;
30+
import com.bytedance.bitsail.common.util.DateUtil;
2931
import com.bytedance.bitsail.connector.doris.DorisConnectionHolder;
3032
import com.bytedance.bitsail.connector.doris.committer.DorisCommittable;
3133
import com.bytedance.bitsail.connector.doris.committer.DorisCommittableSerializer;
@@ -36,6 +38,7 @@
3638
import com.bytedance.bitsail.connector.doris.option.DorisWriterOptions;
3739
import com.bytedance.bitsail.connector.doris.partition.DorisPartition;
3840
import com.bytedance.bitsail.connector.doris.partition.DorisPartitionManager;
41+
import com.bytedance.bitsail.connector.doris.partition.DorisPartitionTemplate;
3942
import com.bytedance.bitsail.connector.doris.sink.ddl.DorisSchemaManagerGenerator;
4043

4144
import com.alibaba.fastjson.JSON;
@@ -44,11 +47,9 @@
4447

4548
import java.io.IOException;
4649
import java.sql.SQLException;
47-
import java.util.HashMap;
48-
import java.util.List;
49-
import java.util.Map;
50-
import java.util.Optional;
51-
import java.util.Properties;
50+
import java.text.ParseException;
51+
import java.text.SimpleDateFormat;
52+
import java.util.*;
5253
import java.util.stream.Collectors;
5354

5455
public class DorisSink<InputT> implements Sink<InputT, DorisCommittable, DorisWriterState> {
@@ -137,16 +138,38 @@ private void initDorisOptions(BitSailConfiguration writerConfiguration) {
137138
// Need partition info in batch replace modes.
138139
if (isHasPartition && this.writeMode.equals(DorisExecutionOptions.WRITE_MODE.BATCH_REPLACE)) {
139140
//BATCH and REPLACE mode need the partition infos
140-
List<Map<String, Object>> partitionList = writerConfiguration.getNecessaryOption(DorisWriterOptions.PARTITIONS, CommonErrorCode.CONFIG_ERROR);
141-
builder.partitions(
142-
partitionList.stream()
143-
.map(partition -> JSON.parseObject(JSON.toJSONString(partition), DorisPartition.class))
144-
.collect(Collectors.toList())
145-
);
141+
DorisPartitionTemplate dorisPartitionTemplate = writerConfiguration.getNecessaryOption(DorisWriterOptions.PARTITIONS, CommonErrorCode.CONFIG_ERROR);
142+
List<DorisPartition> dorisPartitions = parseTemplateToDorisPartitions(dorisPartitionTemplate);
143+
builder.partitions(dorisPartitions);
146144
}
147145
dorisOptions = builder.build();
148146
}
149147

148+
private List<DorisPartition> parseTemplateToDorisPartitions(DorisPartitionTemplate dorisPartitionTemplate){
149+
String pattern = dorisPartitionTemplate.getPattern();
150+
String prefix = dorisPartitionTemplate.getPrefix();
151+
String start = dorisPartitionTemplate.getStartRange();
152+
String end = dorisPartitionTemplate.getEndRange();
153+
154+
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
155+
try {
156+
Date dStart = sdf.parse(start);
157+
Date dEnd = sdf.parse(end);
158+
List<DorisPartition> dorisPartitions = new ArrayList<>();
159+
List<Date> listDate = DateUtil.getDatesBetweenTwoDate(dStart, dEnd);
160+
listDate.forEach(date->{
161+
DorisPartition dorisPartition = new DorisPartition();
162+
dorisPartition.setName(prefix + sdf.format(date));
163+
dorisPartition.setStartRange(Collections.singletonList(sdf.format(date)));
164+
dorisPartition.setEndRange(Collections.singletonList(sdf.format(DateUtil.getNDaysAfterDate(date, 1))));
165+
dorisPartitions.add(dorisPartition);
166+
});
167+
return dorisPartitions;
168+
} catch (ParseException e) {
169+
throw BitSailException.asBitSailException(CommonErrorCode.CONFIG_ERROR, "Can't parse configuration info: " + dorisPartitionTemplate, e);
170+
}
171+
}
172+
150173
private void initDorisExecutionOptions(BitSailConfiguration writerConfiguration) {
151174
LOG.info("Start to init DorisExecutionOptions!");
152175
final DorisExecutionOptions.DorisExecutionOptionsBuilder builder = DorisExecutionOptions.builder();

0 commit comments

Comments
 (0)