embulk-filter-add_time 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +3 -0
  5. data/COPYING +14 -0
  6. data/README.md +212 -0
  7. data/build.gradle +82 -0
  8. data/gradle/check.gradle +34 -0
  9. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  10. data/gradle/wrapper/gradle-wrapper.properties +6 -0
  11. data/gradlew +164 -0
  12. data/gradlew.bat +90 -0
  13. data/lib/embulk/filter/add_time.rb +3 -0
  14. data/src/main/java/org/embulk/filter/add_time/AddTimeFilterPlugin.java +208 -0
  15. data/src/main/java/org/embulk/filter/add_time/converter/ColumnConverter.java +14 -0
  16. data/src/main/java/org/embulk/filter/add_time/converter/ColumnDuplicator.java +72 -0
  17. data/src/main/java/org/embulk/filter/add_time/converter/LongValueCastConverter.java +33 -0
  18. data/src/main/java/org/embulk/filter/add_time/converter/SchemaConverter.java +257 -0
  19. data/src/main/java/org/embulk/filter/add_time/converter/SimpleColumnConverter.java +62 -0
  20. data/src/main/java/org/embulk/filter/add_time/converter/StringValueCastConverter.java +33 -0
  21. data/src/main/java/org/embulk/filter/add_time/converter/TimestampValueCastConverter.java +23 -0
  22. data/src/main/java/org/embulk/filter/add_time/converter/ValueCastConverter.java +108 -0
  23. data/src/main/java/org/embulk/filter/add_time/converter/ValueConverter.java +22 -0
  24. data/src/main/java/org/embulk/filter/add_time/converter/ValueNoConverter.java +46 -0
  25. data/src/main/java/org/embulk/filter/add_time/reader/AbstractColumnReader.java +55 -0
  26. data/src/main/java/org/embulk/filter/add_time/reader/BooleanColumnReader.java +35 -0
  27. data/src/main/java/org/embulk/filter/add_time/reader/ColumnReader.java +14 -0
  28. data/src/main/java/org/embulk/filter/add_time/reader/DoubleColumnReader.java +35 -0
  29. data/src/main/java/org/embulk/filter/add_time/reader/LongColumnReader.java +35 -0
  30. data/src/main/java/org/embulk/filter/add_time/reader/StringColumnReader.java +35 -0
  31. data/src/main/java/org/embulk/filter/add_time/reader/TimeValueGenerator.java +177 -0
  32. data/src/main/java/org/embulk/filter/add_time/reader/TimestampColumnReader.java +36 -0
  33. data/src/test/java/org/embulk/filter/add_time/TestAddTimeFilterPlugin.java +416 -0
  34. data/src/test/java/org/embulk/filter/add_time/converter/TestSchemaConverter.java +338 -0
  35. metadata +107 -0
@@ -0,0 +1,35 @@
1
+ package org.embulk.filter.add_time.reader;
2
+
3
+ import org.embulk.filter.add_time.converter.ValueConverter;
4
+ import org.embulk.spi.Column;
5
+ import org.embulk.spi.PageBuilder;
6
+ import org.embulk.spi.PageReader;
7
+
8
+ public class StringColumnReader
9
+ extends AbstractColumnReader<StringColumnReader>
10
+ {
11
+ protected String value;
12
+
13
+ public StringColumnReader(ValueConverter valueConverter)
14
+ {
15
+ super(valueConverter);
16
+ }
17
+
18
+ @Override
19
+ public void readNonNullValue(Column column, PageReader pageReader)
20
+ {
21
+ value = pageReader.getString(column);
22
+ }
23
+
24
+ @Override
25
+ public void convertNonNullValue(Column column, PageBuilder pageBuilder)
26
+ {
27
+ valueConverter.convertValue(column, value, pageBuilder);
28
+ }
29
+
30
+ @Override
31
+ public void copyValueTo(StringColumnReader columnReader)
32
+ {
33
+ columnReader.value = this.value;
34
+ }
35
+ }
@@ -0,0 +1,177 @@
1
+ package org.embulk.filter.add_time.reader;
2
+
3
+ import com.google.common.base.Optional;
4
+ import org.embulk.config.ConfigException;
5
+ import org.embulk.filter.add_time.AddTimeFilterPlugin.FromValueConfig;
6
+ import org.embulk.filter.add_time.AddTimeFilterPlugin.UnixTimestampUnit;
7
+ import org.embulk.filter.add_time.converter.ValueConverter;
8
+ import org.embulk.spi.Column;
9
+ import org.embulk.spi.Exec;
10
+ import org.embulk.spi.PageBuilder;
11
+ import org.embulk.spi.PageReader;
12
+ import org.embulk.spi.time.Timestamp;
13
+ import org.embulk.spi.time.TimestampParser;
14
+
15
+ public abstract class TimeValueGenerator
16
+ implements ColumnReader
17
+ {
18
+ private final ValueConverter valueConverter;
19
+
20
+ public TimeValueGenerator(ValueConverter valueConverter)
21
+ {
22
+ this.valueConverter = valueConverter;
23
+ }
24
+
25
+ protected abstract Timestamp nextTimestamp();
26
+
27
+ @Override
28
+ public void readValue(Column column, PageReader pageReader)
29
+ {
30
+ throw new AssertionError("Never call");
31
+ }
32
+
33
+ @Override
34
+ public void convertValue(Column column, PageBuilder pageBuilder)
35
+ {
36
+ valueConverter.convertValue(column, nextTimestamp(), pageBuilder);
37
+ }
38
+
39
+ @Override
40
+ public void copyTo(ColumnReader columnReader)
41
+ {
42
+ throw new AssertionError("Never call");
43
+ }
44
+
45
+ public static TimeValueGenerator newGenerator(final FromValueConfig config, ValueConverter valueConverter)
46
+ {
47
+ switch (config.getMode()) {
48
+ case "fixed_time":
49
+ require(config.getValue(), "'value'");
50
+ reject(config.getFrom(), "'from'");
51
+ reject(config.getTo(), "'to'");
52
+ return new FixedTimeValueGenerator(config, valueConverter);
53
+
54
+ case "incremental_time": // default mode
55
+ require(config.getFrom(), "'from', 'to'");
56
+ require(config.getTo(), "'to'");
57
+ reject(config.getValue(), "'value'");
58
+ return new IncrementalTimeValueGenerator(config, valueConverter);
59
+
60
+ case "upload_time":
61
+ reject(config.getFrom(), "'value'");
62
+ reject(config.getFrom(), "'from'");
63
+ reject(config.getTo(), "'to'");
64
+ return new UploadTimeValueGenerator(valueConverter);
65
+
66
+ default:
67
+ throw new ConfigException(String.format("Unknwon mode '%s'. Supported methods are incremental_time, fixed_time.", config.getMode()));
68
+ }
69
+ }
70
+
71
+ public static class IncrementalTimeValueGenerator
72
+ extends TimeValueGenerator
73
+ {
74
+ private final Timestamp from;
75
+ private final Timestamp to;
76
+
77
+ private Timestamp current;
78
+
79
+ public IncrementalTimeValueGenerator(final FromValueConfig config, ValueConverter valueConverter)
80
+ {
81
+ super(valueConverter);
82
+ current = from = toTimestamp(config, config.getFrom().get());
83
+ to = toTimestamp(config, config.getTo().get());
84
+ }
85
+
86
+ @Override
87
+ public Timestamp nextTimestamp()
88
+ {
89
+ try {
90
+ Timestamp ret = current;
91
+ current = Timestamp.ofEpochSecond(current.getEpochSecond() + 1, current.getNano());
92
+ return ret;
93
+ }
94
+ finally {
95
+ if (current.compareTo(to) > 0) {
96
+ current = from;
97
+ }
98
+ }
99
+ }
100
+ }
101
+
102
+ public static class FixedTimeValueGenerator
103
+ extends TimeValueGenerator
104
+ {
105
+ private final Timestamp value;
106
+
107
+ public FixedTimeValueGenerator(FromValueConfig config, ValueConverter valueConverter)
108
+ {
109
+ this(toTimestamp(config, config.getValue().get()), valueConverter);
110
+ }
111
+
112
+ public FixedTimeValueGenerator(Timestamp value, ValueConverter valueConverter)
113
+ {
114
+ super(valueConverter);
115
+ this.value = value;
116
+ }
117
+
118
+ @Override
119
+ public Timestamp nextTimestamp()
120
+ {
121
+ return value;
122
+ }
123
+
124
+ }
125
+
126
+ public static class UploadTimeValueGenerator
127
+ extends FixedTimeValueGenerator
128
+ {
129
+ public UploadTimeValueGenerator(ValueConverter valueConverter)
130
+ {
131
+ super(Exec.getTransactionTime(), valueConverter);
132
+ }
133
+ }
134
+
135
+ // ported from embulk-input-s3
136
+ private static <T> T require(Optional<T> value, String message)
137
+ {
138
+ if (value.isPresent()) {
139
+ return typeCheck(value.get(), message);
140
+ }
141
+ else {
142
+ throw new ConfigException("Required option is not set: " + message);
143
+ }
144
+ }
145
+
146
+ // ported from embulk-input-s3
147
+ private static <T> void reject(Optional<T> value, String message)
148
+ {
149
+ if (value.isPresent()) {
150
+ throw new ConfigException("Invalid option is set: " + message);
151
+ }
152
+ }
153
+
154
+ private static <T> T typeCheck(T value, String message)
155
+ {
156
+ if (value instanceof String || value instanceof Number) {
157
+ return value;
158
+ }
159
+ else {
160
+ throw new ConfigException("Required option must be string or long: " + message);
161
+ }
162
+ }
163
+
164
+ private static Timestamp toTimestamp(FromValueConfig config, Object time)
165
+ {
166
+ if (time instanceof String) {
167
+ return new TimestampParser(config, config).parse((String) time); // TODO optimize?
168
+ }
169
+ else if (time instanceof Number) {
170
+ long t = ((Number) time).longValue();
171
+ return UnixTimestampUnit.of(config.getUnixTimestampUnit()).toTimestamp(t);
172
+ }
173
+ else {
174
+ throw new RuntimeException();
175
+ }
176
+ }
177
+ }
@@ -0,0 +1,36 @@
1
+ package org.embulk.filter.add_time.reader;
2
+
3
+ import org.embulk.filter.add_time.converter.ValueConverter;
4
+ import org.embulk.spi.Column;
5
+ import org.embulk.spi.PageBuilder;
6
+ import org.embulk.spi.PageReader;
7
+ import org.embulk.spi.time.Timestamp;
8
+
9
+ public class TimestampColumnReader
10
+ extends AbstractColumnReader<TimestampColumnReader>
11
+ {
12
+ protected Timestamp value;
13
+
14
+ public TimestampColumnReader(ValueConverter valueConverter)
15
+ {
16
+ super(valueConverter);
17
+ }
18
+
19
+ @Override
20
+ public void readNonNullValue(Column column, PageReader pageReader)
21
+ {
22
+ value = pageReader.getTimestamp(column);
23
+ }
24
+
25
+ @Override
26
+ public void convertNonNullValue(Column column, PageBuilder pageBuilder)
27
+ {
28
+ valueConverter.convertValue(column, value, pageBuilder);
29
+ }
30
+
31
+ @Override
32
+ public void copyValueTo(TimestampColumnReader columnReader)
33
+ {
34
+ columnReader.value = this.value;
35
+ }
36
+ }
@@ -0,0 +1,416 @@
1
+ package org.embulk.filter.add_time;
2
+
3
+ import com.google.common.collect.ImmutableMap;
4
+ import org.embulk.EmbulkTestRuntime;
5
+ import org.embulk.config.ConfigSource;
6
+ import org.embulk.config.TaskSource;
7
+ import org.embulk.filter.add_time.AddTimeFilterPlugin.PluginTask;
8
+ import org.embulk.spi.FilterPlugin;
9
+ import org.embulk.spi.Page;
10
+ import org.embulk.spi.PageOutput;
11
+ import org.embulk.spi.PageTestUtils;
12
+ import org.embulk.spi.Schema;
13
+ import org.embulk.spi.TestPageBuilderReader.MockPageOutput;
14
+ import org.embulk.spi.time.Timestamp;
15
+ import org.embulk.spi.type.Type;
16
+ import org.embulk.spi.type.Types;
17
+ import org.embulk.spi.util.Pages;
18
+ import org.junit.Before;
19
+ import org.junit.Rule;
20
+ import org.junit.Test;
21
+
22
+ import java.util.List;
23
+
24
+ import static org.junit.Assert.assertEquals;
25
+ import static org.mockito.Mockito.spy;
26
+
27
+ public class TestAddTimeFilterPlugin
28
+ {
29
+ @Rule
30
+ public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
31
+
32
+ private AddTimeFilterPlugin plugin;
33
+ private ConfigSource config;
34
+ private Schema inputSchema;
35
+ private List<Object[]> records;
36
+
37
+ @Before
38
+ public void createResources()
39
+ {
40
+ plugin = plugin();
41
+ config = runtime.getExec().newConfigSource();
42
+ inputSchema = schema("c0", Types.BOOLEAN, "c1", Types.LONG, "c2", Types.DOUBLE, "c3", Types.STRING, "c4", Types.TIMESTAMP);
43
+ }
44
+
45
+ @Test
46
+ public void testFromColumn()
47
+ {
48
+ { // long type
49
+ ConfigSource conf = this.config.deepCopy()
50
+ .set("to_column", ImmutableMap.of("name", "time"))
51
+ .set("from_column", ImmutableMap.of("name", "c1", "unix_timestamp_unit", "sec"));
52
+ List<Page> pages = newPages(true, 1451646671L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
53
+
54
+ callTansaction(conf, inputSchema, pages);
55
+
56
+ assertEquals(1, records.size());
57
+ for (Object[] record : records) {
58
+ assertEquals(inputSchema.size() + 1, record.length);
59
+
60
+ assertEquals(true, record[0]);
61
+ assertEquals(1451646671L, record[1]);
62
+ assertEquals(0.1, record[2]);
63
+ assertEquals("foo", record[3]);
64
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
65
+ assertEquals(1451646671L, ((Timestamp) record[5]).getEpochSecond());
66
+ }
67
+ }
68
+
69
+ { // timestamp type
70
+ ConfigSource conf = this.config.deepCopy()
71
+ .set("to_column", ImmutableMap.of("name", "time"))
72
+ .set("from_column", ImmutableMap.of("name", "c4"));
73
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
74
+
75
+ callTansaction(conf, inputSchema, pages);
76
+
77
+ assertEquals(1, records.size());
78
+ for (Object[] record : records) {
79
+ assertEquals(inputSchema.size() + 1, record.length);
80
+
81
+ assertEquals(true, record[0]);
82
+ assertEquals(0L, record[1]);
83
+ assertEquals(0.1, record[2]);
84
+ assertEquals("foo", record[3]);
85
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
86
+ assertEquals(1451646671L, ((Timestamp) record[5]).getEpochSecond());
87
+ }
88
+ }
89
+
90
+ { // string type
91
+ ConfigSource conf = this.config.deepCopy()
92
+ .set("to_column", ImmutableMap.of("name", "time"))
93
+ .set("from_column", ImmutableMap.of("name", "c3"));
94
+ List<Page> pages = newPages(true, 0L, 0.1, "2016-01-01 11:11:11 UTC", Timestamp.ofEpochSecond(1451646671));
95
+
96
+ callTansaction(conf, inputSchema, pages);
97
+
98
+ assertEquals(1, records.size());
99
+ for (Object[] record : records) {
100
+ assertEquals(inputSchema.size() + 1, record.length);
101
+
102
+ assertEquals(true, record[0]);
103
+ assertEquals(0L, record[1]);
104
+ assertEquals(0.1, record[2]);
105
+ assertEquals("2016-01-01 11:11:11 UTC", record[3]);
106
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
107
+ assertEquals(1451646671L, ((Timestamp) record[5]).getEpochSecond());
108
+ }
109
+ }
110
+ }
111
+
112
+ @Test
113
+ public void testFromValue()
114
+ {
115
+ // mode: fixed_time
116
+ {
117
+ ConfigSource conf = this.config.deepCopy()
118
+ .set("to_column", ImmutableMap.of("name", "time"))
119
+ .set("from_value", ImmutableMap.of("mode", "fixed_time", "value", "2016-01-01 11:11:11 UTC"));
120
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
121
+
122
+ callTansaction(conf, inputSchema, pages);
123
+
124
+ assertEquals(1, records.size());
125
+ for (Object[] record : records) {
126
+ assertEquals(inputSchema.size() + 1, record.length);
127
+
128
+ assertEquals(true, record[0]);
129
+ assertEquals(0L, record[1]);
130
+ assertEquals(0.1, record[2]);
131
+ assertEquals("foo", record[3]);
132
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
133
+ assertEquals(1451646671L, ((Timestamp) record[5]).getEpochSecond());
134
+ }
135
+ }
136
+ { // specifies timestamp_format
137
+ ConfigSource conf = this.config.deepCopy()
138
+ .set("to_column", ImmutableMap.of("name", "time"))
139
+ .set("from_value", ImmutableMap.of("mode", "fixed_time", "value", "2016-01-01 11:11:11.000 UTC", "timestamp_format", "%Y-%m-%d %H:%M:%S.%N %Z"));
140
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
141
+
142
+ callTansaction(conf, inputSchema, pages);
143
+
144
+ assertEquals(1, records.size());
145
+ for (Object[] record : records) {
146
+ assertEquals(inputSchema.size() + 1, record.length);
147
+
148
+ assertEquals(true, record[0]);
149
+ assertEquals(0L, record[1]);
150
+ assertEquals(0.1, record[2]);
151
+ assertEquals("foo", record[3]);
152
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
153
+ assertEquals(1451646671L, ((Timestamp) record[5]).getEpochSecond());
154
+ }
155
+ }
156
+ { // specifies unix_timestamp_unit
157
+ ConfigSource conf = this.config.deepCopy()
158
+ .set("to_column", ImmutableMap.of("name", "time"))
159
+ .set("from_value", ImmutableMap.of("mode", "fixed_time", "value", 1451646671, "unix_timestamp_unit", "sec"));
160
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
161
+
162
+ callTansaction(conf, inputSchema, pages);
163
+
164
+ assertEquals(1, records.size());
165
+ for (Object[] record : records) {
166
+ assertEquals(inputSchema.size() + 1, record.length);
167
+
168
+ assertEquals(true, record[0]);
169
+ assertEquals(0L, record[1]);
170
+ assertEquals(0.1, record[2]);
171
+ assertEquals("foo", record[3]);
172
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
173
+ assertEquals(1451646671L, ((Timestamp) record[5]).getEpochSecond());
174
+ }
175
+ }
176
+
177
+ // mode: incremental_time
178
+ {
179
+ ConfigSource conf = this.config.deepCopy()
180
+ .set("to_column", ImmutableMap.of("name", "time"))
181
+ .set("from_value", ImmutableMap.of("mode", "incremental_time",
182
+ "from", "2016-01-01 11:11:11 UTC", "to", "2016-01-01 11:11:12 UTC"));
183
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
184
+
185
+ callTansaction(conf, inputSchema, pages);
186
+
187
+ assertEquals(1, records.size());
188
+ for (Object[] record : records) {
189
+ assertEquals(inputSchema.size() + 1, record.length);
190
+
191
+ assertEquals(true, record[0]);
192
+ assertEquals(0L, record[1]);
193
+ assertEquals(0.1, record[2]);
194
+ assertEquals("foo", record[3]);
195
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
196
+ assertEquals(1451646671L, ((Timestamp) record[5]).getEpochSecond());
197
+ }
198
+ }
199
+ { // specifies timestamp_format
200
+ ConfigSource conf = this.config.deepCopy()
201
+ .set("to_column", ImmutableMap.of("name", "time"))
202
+ .set("from_value", ImmutableMap.of("mode", "incremental_time",
203
+ "from", "2016-01-01 11:11:11.000 UTC", "to", "2016-01-01 11:11:12.000 UTC", "timestamp_format", "%Y-%m-%d %H:%M:%S.%N %Z"));
204
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
205
+
206
+ callTansaction(conf, inputSchema, pages);
207
+
208
+ assertEquals(1, records.size());
209
+ for (Object[] record : records) {
210
+ assertEquals(inputSchema.size() + 1, record.length);
211
+
212
+ assertEquals(true, record[0]);
213
+ assertEquals(0L, record[1]);
214
+ assertEquals(0.1, record[2]);
215
+ assertEquals("foo", record[3]);
216
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
217
+ assertEquals(1451646671L, ((Timestamp) record[5]).getEpochSecond());
218
+ }
219
+ }
220
+ { // specifies unix_timestamp_unit
221
+ ConfigSource conf = this.config.deepCopy()
222
+ .set("to_column", ImmutableMap.of("name", "time"))
223
+ .set("from_value", ImmutableMap.of("mode", "incremental_time",
224
+ "from", 1451646671, "to", 1451646672, "unix_timestamp_unit", "sec"));
225
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
226
+
227
+ callTansaction(conf, inputSchema, pages);
228
+
229
+ assertEquals(1, records.size());
230
+ for (Object[] record : records) {
231
+ assertEquals(inputSchema.size() + 1, record.length);
232
+
233
+ assertEquals(true, record[0]);
234
+ assertEquals(0L, record[1]);
235
+ assertEquals(0.1, record[2]);
236
+ assertEquals("foo", record[3]);
237
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
238
+ assertEquals(1451646671L, ((Timestamp) record[5]).getEpochSecond());
239
+ }
240
+ }
241
+
242
+ // mode: upload_time
243
+ {
244
+ ConfigSource conf = this.config.deepCopy()
245
+ .set("to_column", ImmutableMap.of("name", "time"))
246
+ .set("from_value", ImmutableMap.of("mode", "upload_time"));
247
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
248
+
249
+ callTansaction(conf, inputSchema, pages);
250
+
251
+ assertEquals(1, records.size());
252
+ for (Object[] record : records) {
253
+ assertEquals(inputSchema.size() + 1, record.length);
254
+
255
+ assertEquals(true, record[0]);
256
+ assertEquals(0L, record[1]);
257
+ assertEquals(0.1, record[2]);
258
+ assertEquals("foo", record[3]);
259
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
260
+ assertEquals(runtime.getExec().getTransactionTime(), record[5]);
261
+ }
262
+ }
263
+ }
264
+
265
+ @Test
266
+ public void testToColumn()
267
+ {
268
+ // timestamp type
269
+ {
270
+ ConfigSource conf = this.config.deepCopy()
271
+ .set("to_column", ImmutableMap.of("name", "time"))
272
+ .set("from_value", ImmutableMap.of("mode", "fixed_time", "value", "2016-01-01 11:11:11 UTC"));
273
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
274
+
275
+ callTansaction(conf, inputSchema, pages);
276
+
277
+ assertEquals(1, records.size());
278
+ for (Object[] record : records) {
279
+ assertEquals(inputSchema.size() + 1, record.length);
280
+
281
+ assertEquals(true, record[0]);
282
+ assertEquals(0L, record[1]);
283
+ assertEquals(0.1, record[2]);
284
+ assertEquals("foo", record[3]);
285
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
286
+ assertEquals(1451646671L, ((Timestamp) record[5]).getEpochSecond());
287
+ }
288
+ }
289
+
290
+ // long type
291
+ { // unix_timestamp: sec
292
+ ConfigSource conf = this.config.deepCopy()
293
+ .set("to_column", ImmutableMap.of("name", "time", "type", "long", "unix_timestamp_unit", "sec"))
294
+ .set("from_value", ImmutableMap.of("mode", "fixed_time", "value", "2016-01-01 11:11:11 UTC"));
295
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
296
+
297
+ callTansaction(conf, inputSchema, pages);
298
+
299
+ assertEquals(1, records.size());
300
+ for (Object[] record : records) {
301
+ assertEquals(inputSchema.size() + 1, record.length);
302
+
303
+ assertEquals(true, record[0]);
304
+ assertEquals(0L, record[1]);
305
+ assertEquals(0.1, record[2]);
306
+ assertEquals("foo", record[3]);
307
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
308
+ assertEquals(1451646671L, record[5]);
309
+ }
310
+ }
311
+ { // unix_timestamp: milli
312
+ ConfigSource conf = this.config.deepCopy()
313
+ .set("to_column", ImmutableMap.of("name", "time", "type", "long", "unix_timestamp_unit", "milli"))
314
+ .set("from_value", ImmutableMap.of("mode", "fixed_time", "value", "2016-01-01 11:11:11 UTC"));
315
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
316
+
317
+ callTansaction(conf, inputSchema, pages);
318
+
319
+ assertEquals(1, records.size());
320
+ for (Object[] record : records) {
321
+ assertEquals(inputSchema.size() + 1, record.length);
322
+
323
+ assertEquals(true, record[0]);
324
+ assertEquals(0L, record[1]);
325
+ assertEquals(0.1, record[2]);
326
+ assertEquals("foo", record[3]);
327
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
328
+ assertEquals(1451646671000L, record[5]);
329
+ }
330
+ }
331
+ { // unix_timestamp: micro
332
+ ConfigSource conf = this.config.deepCopy()
333
+ .set("to_column", ImmutableMap.of("name", "time", "type", "long", "unix_timestamp_unit", "micro"))
334
+ .set("from_value", ImmutableMap.of("mode", "fixed_time", "value", "2016-01-01 11:11:11 UTC"));
335
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
336
+
337
+ callTansaction(conf, inputSchema, pages);
338
+
339
+ assertEquals(1, records.size());
340
+ for (Object[] record : records) {
341
+ assertEquals(inputSchema.size() + 1, record.length);
342
+
343
+ assertEquals(true, record[0]);
344
+ assertEquals(0L, record[1]);
345
+ assertEquals(0.1, record[2]);
346
+ assertEquals("foo", record[3]);
347
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
348
+ assertEquals(1451646671000000L, record[5]);
349
+ }
350
+ }
351
+ { // unix_timestamp: nano
352
+ ConfigSource conf = this.config.deepCopy()
353
+ .set("to_column", ImmutableMap.of("name", "time", "type", "long", "unix_timestamp_unit", "nano"))
354
+ .set("from_value", ImmutableMap.of("mode", "fixed_time", "value", "2016-01-01 11:11:11 UTC"));
355
+ List<Page> pages = newPages(true, 0L, 0.1, "foo", Timestamp.ofEpochSecond(1451646671));
356
+
357
+ callTansaction(conf, inputSchema, pages);
358
+
359
+ assertEquals(1, records.size());
360
+ for (Object[] record : records) {
361
+ assertEquals(inputSchema.size() + 1, record.length);
362
+
363
+ assertEquals(true, record[0]);
364
+ assertEquals(0L, record[1]);
365
+ assertEquals(0.1, record[2]);
366
+ assertEquals("foo", record[3]);
367
+ assertEquals(1451646671L, ((Timestamp) record[4]).getEpochSecond());
368
+ assertEquals(1451646671000000000L, record[5]);
369
+ }
370
+ }
371
+ }
372
+
373
+ private List<Page> newPages(Object... values)
374
+ {
375
+ return PageTestUtils.buildPage(runtime.getBufferAllocator(), inputSchema, values);
376
+ }
377
+
378
+ private void callTansaction(ConfigSource conf, final Schema inputSchema, final List<Page> pages)
379
+ {
380
+ final MockPageOutput output = new MockPageOutput();
381
+ plugin.transaction(conf, inputSchema, new FilterPlugin.Control() {
382
+ @Override
383
+ public void run(TaskSource taskSource, Schema outputSchema)
384
+ {
385
+ try (PageOutput out = plugin.open(taskSource, inputSchema, outputSchema, output)) {
386
+ for (Page page : pages) {
387
+ out.add(page);
388
+ }
389
+ out.finish();
390
+ }
391
+ records = Pages.toObjects(outputSchema, output.pages);
392
+ }
393
+ });
394
+ }
395
+
396
+ public static Schema schema(Object... nameAndTypes)
397
+ {
398
+ Schema.Builder builder = Schema.builder();
399
+ for (int i = 0; i < nameAndTypes.length; i += 2) {
400
+ String name = (String) nameAndTypes[i];
401
+ Type type = (Type) nameAndTypes[i + 1];
402
+ builder.add(name, type);
403
+ }
404
+ return builder.build();
405
+ }
406
+
407
+ public static PluginTask pluginTask(ConfigSource config)
408
+ {
409
+ return config.loadConfig(PluginTask.class);
410
+ }
411
+
412
+ public static AddTimeFilterPlugin plugin()
413
+ {
414
+ return spy(new AddTimeFilterPlugin());
415
+ }
416
+ }