embulk-parser-jsonpath 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +5 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +107 -0
  7. data/build.gradle +111 -0
  8. data/config/checkstyle/checkstyle.xml +128 -0
  9. data/config/checkstyle/default.xml +108 -0
  10. data/example/conf.yml +18 -0
  11. data/example/dummy.rb +27 -0
  12. data/example/input.json +1006 -0
  13. data/example/input2.json +1006 -0
  14. data/example/seed.yml +8 -0
  15. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  16. data/gradle/wrapper/gradle-wrapper.properties +6 -0
  17. data/gradlew +160 -0
  18. data/gradlew.bat +90 -0
  19. data/lib/embulk/guess/jsonpath.rb +61 -0
  20. data/lib/embulk/parser/jsonpath.rb +3 -0
  21. data/src/main/java/org/embulk/parser/jsonpath/ColumnCaster.java +97 -0
  22. data/src/main/java/org/embulk/parser/jsonpath/ColumnVisitorImpl.java +167 -0
  23. data/src/main/java/org/embulk/parser/jsonpath/JsonRecordValidateException.java +22 -0
  24. data/src/main/java/org/embulk/parser/jsonpath/JsonpathParserPlugin.java +148 -0
  25. data/src/main/java/org/embulk/parser/jsonpath/cast/BooleanCast.java +39 -0
  26. data/src/main/java/org/embulk/parser/jsonpath/cast/DoubleCast.java +41 -0
  27. data/src/main/java/org/embulk/parser/jsonpath/cast/JsonCast.java +40 -0
  28. data/src/main/java/org/embulk/parser/jsonpath/cast/LongCast.java +47 -0
  29. data/src/main/java/org/embulk/parser/jsonpath/cast/StringCast.java +82 -0
  30. data/src/test/java/org/embulk/parser/jsonpath/TestColumnCaster.java +256 -0
  31. data/src/test/java/org/embulk/parser/jsonpath/TestJsonpathParserPlugin.java +292 -0
  32. data/src/test/java/org/embulk/parser/jsonpath/cast/TestBooleanCast.java +56 -0
  33. data/src/test/java/org/embulk/parser/jsonpath/cast/TestDoubleCast.java +49 -0
  34. data/src/test/java/org/embulk/parser/jsonpath/cast/TestJsonCast.java +79 -0
  35. data/src/test/java/org/embulk/parser/jsonpath/cast/TestLongCast.java +41 -0
  36. data/src/test/java/org/embulk/parser/jsonpath/cast/TestStringCast.java +103 -0
  37. metadata +113 -0
@@ -0,0 +1,22 @@
1
+ package org.embulk.parser.jsonpath;
2
+
3
+ import org.embulk.spi.DataException;
4
+
5
+ public class JsonRecordValidateException
6
+ extends DataException
7
+ {
8
+ public JsonRecordValidateException(String message)
9
+ {
10
+ super(message);
11
+ }
12
+
13
+ public JsonRecordValidateException(String message, Throwable cause)
14
+ {
15
+ super(message, cause);
16
+ }
17
+
18
+ public JsonRecordValidateException(Throwable cause)
19
+ {
20
+ super(cause);
21
+ }
22
+ }
@@ -0,0 +1,148 @@
1
+ package org.embulk.parser.jsonpath;
2
+
3
+ import com.google.common.base.Optional;
4
+ import com.google.common.collect.ImmutableMap;
5
+ import com.jayway.jsonpath.JsonPath;
6
+ import org.embulk.config.Config;
7
+ import org.embulk.config.ConfigDefault;
8
+ import org.embulk.config.ConfigSource;
9
+ import org.embulk.config.Task;
10
+ import org.embulk.config.TaskSource;
11
+ import org.embulk.spi.Column;
12
+ import org.embulk.spi.DataException;
13
+ import org.embulk.spi.Exec;
14
+ import org.embulk.spi.FileInput;
15
+ import org.embulk.spi.PageBuilder;
16
+ import org.embulk.spi.PageOutput;
17
+ import org.embulk.spi.ParserPlugin;
18
+ import org.embulk.spi.Schema;
19
+ import org.embulk.spi.SchemaConfig;
20
+ import org.embulk.spi.json.JsonParser;
21
+ import org.embulk.spi.time.TimestampParser;
22
+ import org.embulk.spi.util.FileInputInputStream;
23
+ import org.embulk.spi.util.Timestamps;
24
+ import org.msgpack.value.Value;
25
+ import org.slf4j.Logger;
26
+
27
+ import java.io.IOException;
28
+ import java.util.Map;
29
+
30
+ import static java.util.Locale.ENGLISH;
31
+ import static org.msgpack.value.ValueFactory.newString;
32
+
33
+ public class JsonpathParserPlugin
34
+ implements ParserPlugin
35
+ {
36
+
37
+ private static final Logger logger = Exec.getLogger(JsonpathParserPlugin.class);
38
+
39
+ private Map<String, Value> columnNameValues;
40
+
41
+ public interface TypecastColumnOption
42
+ extends Task
43
+ {
44
+ @Config("typecast")
45
+ @ConfigDefault("null")
46
+ public Optional<Boolean> getTypecast();
47
+ }
48
+
49
+ public interface PluginTask
50
+ extends Task, TimestampParser.Task
51
+ {
52
+ @Config("root")
53
+ @ConfigDefault("\"$\"")
54
+ public String getRoot();
55
+
56
+ @Config("columns")
57
+ SchemaConfig getSchemaConfig();
58
+
59
+ @Config("default_typecast")
60
+ @ConfigDefault("true")
61
+ Boolean getDefaultTypecast();
62
+
63
+ @Config("stop_on_invalid_record")
64
+ @ConfigDefault("false")
65
+ boolean getStopOnInvalidRecord();
66
+ }
67
+
68
+ @Override
69
+ public void transaction(ConfigSource config, ParserPlugin.Control control)
70
+ {
71
+ PluginTask task = config.loadConfig(PluginTask.class);
72
+
73
+ Schema schema = task.getSchemaConfig().toSchema();
74
+
75
+ control.run(task.dump(), schema);
76
+ }
77
+
78
+ @Override
79
+ public void run(TaskSource taskSource, Schema schema,
80
+ FileInput input, PageOutput output)
81
+ {
82
+ PluginTask task = taskSource.loadTask(PluginTask.class);
83
+ String jsonRoot = task.getRoot();
84
+
85
+ setColumnNameValues(schema);
86
+
87
+ logger.debug("JSONPath = " + jsonRoot);
88
+ final TimestampParser[] timestampParsers = Timestamps.newTimestampColumnParsers(task, task.getSchemaConfig());
89
+ final JsonParser jsonParser = new JsonParser();
90
+ final boolean stopOnInvalidRecord = task.getStopOnInvalidRecord();
91
+
92
+ try (final PageBuilder pageBuilder = new PageBuilder(Exec.getBufferAllocator(), schema, output)) {
93
+ ColumnVisitorImpl visitor = new ColumnVisitorImpl(task, schema, pageBuilder, timestampParsers);
94
+
95
+ try (FileInputInputStream is = new FileInputInputStream(input)) {
96
+ while (is.nextFile()) {
97
+ // TODO more efficient handling.
98
+ String json = JsonPath.read(is, jsonRoot).toString();
99
+ Value value = jsonParser.parse(json);
100
+ if (!value.isArrayValue()) {
101
+ throw new JsonRecordValidateException("Json string is not representing array value.");
102
+ }
103
+
104
+ for (Value recordValue : value.asArrayValue()) {
105
+ if (!recordValue.isMapValue()) {
106
+ if (stopOnInvalidRecord) {
107
+ throw new JsonRecordValidateException("Json string is not representing map value.");
108
+ }
109
+ logger.warn(String.format(ENGLISH, "Skipped invalid record %s", recordValue));
110
+ continue;
111
+ }
112
+
113
+ logger.debug("recordValue = " + recordValue.toString());
114
+ final Map<Value, Value> record = recordValue.asMapValue().map();
115
+ for (Column column : schema.getColumns()) {
116
+ Value v = record.get(getColumnNameValue(column));
117
+ visitor.setValue(v);
118
+ column.visit(visitor);
119
+ }
120
+
121
+ pageBuilder.addRecord();
122
+ }
123
+ }
124
+ }
125
+ catch (IOException e) {
126
+ // TODO more efficient exception handling.
127
+ throw new DataException("catch IOException " + e);
128
+ }
129
+
130
+ pageBuilder.finish();
131
+ }
132
+ }
133
+
134
+ private void setColumnNameValues(Schema schema)
135
+ {
136
+ ImmutableMap.Builder<String, Value> builder = ImmutableMap.builder();
137
+ for (Column column : schema.getColumns()) {
138
+ String name = column.getName();
139
+ builder.put(name, newString(name));
140
+ }
141
+ columnNameValues = builder.build();
142
+ }
143
+
144
+ private Value getColumnNameValue(Column column)
145
+ {
146
+ return columnNameValues.get(column.getName());
147
+ }
148
+ }
@@ -0,0 +1,39 @@
1
+ package org.embulk.parser.jsonpath.cast;
2
+
3
+ import org.embulk.spi.DataException;
4
+ import org.embulk.spi.time.Timestamp;
5
+
6
+ public class BooleanCast
7
+ {
8
+ private BooleanCast() {}
9
+
10
+ private static String buildErrorMessage(String as, boolean value)
11
+ {
12
+ return String.format("cannot cast boolean to %s: \"%s\"", as, value);
13
+ }
14
+
15
+ public static boolean asBoolean(boolean value) throws DataException
16
+ {
17
+ return value;
18
+ }
19
+
20
+ public static long asLong(boolean value) throws DataException
21
+ {
22
+ return value ? 1 : 0;
23
+ }
24
+
25
+ public static double asDouble(boolean value) throws DataException
26
+ {
27
+ throw new DataException(buildErrorMessage("double", value));
28
+ }
29
+
30
+ public static String asString(boolean value) throws DataException
31
+ {
32
+ return value ? "true" : "false";
33
+ }
34
+
35
+ public static Timestamp asTimestamp(boolean value) throws DataException
36
+ {
37
+ throw new DataException(buildErrorMessage("timestamp", value));
38
+ }
39
+ }
@@ -0,0 +1,41 @@
1
+ package org.embulk.parser.jsonpath.cast;
2
+
3
+ import org.embulk.spi.DataException;
4
+ import org.embulk.spi.time.Timestamp;
5
+
6
+ public class DoubleCast
7
+ {
8
+ private DoubleCast() {}
9
+
10
+ private static String buildErrorMessage(String as, double value)
11
+ {
12
+ return String.format("cannot cast double to %s: \"%s\"", as, value);
13
+ }
14
+
15
+ public static boolean asBoolean(double value) throws DataException
16
+ {
17
+ throw new DataException(buildErrorMessage("boolean", value));
18
+ }
19
+
20
+ public static long asLong(double value) throws DataException
21
+ {
22
+ return (long) value;
23
+ }
24
+
25
+ public static double asDouble(double value) throws DataException
26
+ {
27
+ return value;
28
+ }
29
+
30
+ public static String asString(double value) throws DataException
31
+ {
32
+ return String.valueOf(value);
33
+ }
34
+
35
+ public static Timestamp asTimestamp(double value) throws DataException
36
+ {
37
+ long epochSecond = (long) value;
38
+ long nanoAdjustMent = (long) ((value - epochSecond) * 1000000000);
39
+ return Timestamp.ofEpochSecond(epochSecond, nanoAdjustMent);
40
+ }
41
+ }
@@ -0,0 +1,40 @@
1
+ package org.embulk.parser.jsonpath.cast;
2
+
3
+ import org.embulk.spi.DataException;
4
+ import org.embulk.spi.time.Timestamp;
5
+ import org.msgpack.value.Value;
6
+
7
+ public class JsonCast
8
+ {
9
+ private JsonCast() {}
10
+
11
+ private static String buildErrorMessage(String as, Value value)
12
+ {
13
+ return String.format("cannot cast Json to %s: \"%s\"", as, value);
14
+ }
15
+
16
+ public static boolean asBoolean(Value value) throws DataException
17
+ {
18
+ throw new DataException(buildErrorMessage("boolean", value));
19
+ }
20
+
21
+ public static long asLong(Value value) throws DataException
22
+ {
23
+ throw new DataException(buildErrorMessage("long", value));
24
+ }
25
+
26
+ public static double asDouble(Value value) throws DataException
27
+ {
28
+ throw new DataException(buildErrorMessage("double", value));
29
+ }
30
+
31
+ public static String asString(Value value) throws DataException
32
+ {
33
+ return value.toString();
34
+ }
35
+
36
+ public static Timestamp asTimestamp(Value value) throws DataException
37
+ {
38
+ throw new DataException(buildErrorMessage("timestamp", value));
39
+ }
40
+ }
@@ -0,0 +1,47 @@
1
+ package org.embulk.parser.jsonpath.cast;
2
+
3
+ import org.embulk.spi.DataException;
4
+ import org.embulk.spi.time.Timestamp;
5
+
6
+ public class LongCast
7
+ {
8
+ private LongCast() {}
9
+
10
+ private static String buildErrorMessage(String as, long value)
11
+ {
12
+ return String.format("cannot cast long to %s: \"%s\"", as, value);
13
+ }
14
+
15
+ public static boolean asBoolean(long value) throws DataException
16
+ {
17
+ if (value == 1) {
18
+ return true;
19
+ }
20
+ else if (value == 0) {
21
+ return false;
22
+ }
23
+ else {
24
+ throw new DataException(buildErrorMessage("boolean", value));
25
+ }
26
+ }
27
+
28
+ public static long asLong(long value) throws DataException
29
+ {
30
+ return value;
31
+ }
32
+
33
+ public static double asDouble(long value) throws DataException
34
+ {
35
+ return (double) value;
36
+ }
37
+
38
+ public static String asString(long value) throws DataException
39
+ {
40
+ return String.valueOf(value);
41
+ }
42
+
43
+ public static Timestamp asTimestamp(long value) throws DataException
44
+ {
45
+ return Timestamp.ofEpochSecond(value);
46
+ }
47
+ }
@@ -0,0 +1,82 @@
1
+ package org.embulk.parser.jsonpath.cast;
2
+
3
+ import com.google.common.collect.ImmutableSet;
4
+ import org.embulk.spi.DataException;
5
+ import org.embulk.spi.time.Timestamp;
6
+ import org.embulk.spi.time.TimestampParseException;
7
+ import org.embulk.spi.time.TimestampParser;
8
+
9
+ public class StringCast
10
+ {
11
+ // copy from csv plugin
12
+ public static final ImmutableSet<String> TRUE_STRINGS =
13
+ ImmutableSet.of(
14
+ "true", "True", "TRUE",
15
+ "yes", "Yes", "YES",
16
+ "t", "T", "y", "Y",
17
+ "on", "On", "ON",
18
+ "1");
19
+
20
+ public static final ImmutableSet<String> FALSE_STRINGS =
21
+ ImmutableSet.of(
22
+ "false", "False", "FALSE",
23
+ "no", "No", "NO",
24
+ "f", "F", "n", "N",
25
+ "off", "Off", "OFF",
26
+ "0");
27
+
28
+ private StringCast() {}
29
+
30
+ private static String buildErrorMessage(String as, String value)
31
+ {
32
+ return String.format("cannot cast String to %s: \"%s\"", as, value);
33
+ }
34
+
35
+ public static boolean asBoolean(String value) throws DataException
36
+ {
37
+ if (TRUE_STRINGS.contains(value)) {
38
+ return true;
39
+ }
40
+ else if (FALSE_STRINGS.contains(value)) {
41
+ return false;
42
+ }
43
+ else {
44
+ throw new DataException(buildErrorMessage("boolean", value));
45
+ }
46
+ }
47
+
48
+ public static long asLong(String value) throws DataException
49
+ {
50
+ try {
51
+ return Long.parseLong(value);
52
+ }
53
+ catch (NumberFormatException ex) {
54
+ throw new DataException(buildErrorMessage("long", value), ex);
55
+ }
56
+ }
57
+
58
+ public static double asDouble(String value) throws DataException
59
+ {
60
+ try {
61
+ return Double.parseDouble(value);
62
+ }
63
+ catch (NumberFormatException ex) {
64
+ throw new DataException(buildErrorMessage("double", value), ex);
65
+ }
66
+ }
67
+
68
+ public static String asString(String value) throws DataException
69
+ {
70
+ return value;
71
+ }
72
+
73
+ public static Timestamp asTimestamp(String value, TimestampParser parser) throws DataException
74
+ {
75
+ try {
76
+ return parser.parse(value);
77
+ }
78
+ catch (TimestampParseException ex) {
79
+ throw new DataException(buildErrorMessage("timestamp", value), ex);
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,256 @@
1
+ package org.embulk.parser.jsonpath;
2
+
3
+ import org.embulk.EmbulkTestRuntime;
4
+ import org.embulk.spi.DataException;
5
+ import org.embulk.spi.time.Timestamp;
6
+ import org.embulk.spi.time.TimestampParser;
7
+ import org.joda.time.DateTimeZone;
8
+ import org.jruby.embed.ScriptingContainer;
9
+ import org.junit.Before;
10
+ import org.junit.Rule;
11
+ import org.junit.Test;
12
+ import org.msgpack.value.MapValue;
13
+ import org.msgpack.value.Value;
14
+ import org.msgpack.value.ValueFactory;
15
+
16
+ import static org.junit.Assert.assertEquals;
17
+ import static org.junit.Assert.assertTrue;
18
+ import static org.junit.Assert.fail;
19
+
20
+ public class TestColumnCaster
21
+ {
22
+ @Rule
23
+ public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
24
+ public MapValue mapValue;
25
+ public DataException thrown;
26
+ public ScriptingContainer jruby;
27
+ public TimestampParser parser;
28
+
29
+ @Before
30
+ public void createResource()
31
+ {
32
+ jruby = new ScriptingContainer();
33
+ thrown = new DataException("any");
34
+ Value[] kvs = new Value[2];
35
+ kvs[0] = ValueFactory.newString("k");
36
+ kvs[1] = ValueFactory.newString("v");
37
+ mapValue = ValueFactory.newMap(kvs);
38
+ parser = new TimestampParser(jruby, "%Y-%m-%d %H:%M:%S.%N", DateTimeZone.UTC);
39
+ }
40
+
41
+ @Test
42
+ public void asBooleanFromBoolean()
43
+ {
44
+ assertEquals(true, ColumnCaster.asBoolean(ValueFactory.newBoolean(true)));
45
+ }
46
+
47
+ @Test
48
+ public void asBooleanFromInteger()
49
+ {
50
+ assertEquals(true, ColumnCaster.asBoolean(ValueFactory.newInteger(1)));
51
+ try {
52
+ ColumnCaster.asBoolean(ValueFactory.newInteger(2));
53
+ fail();
54
+ }
55
+ catch (Throwable t) {
56
+ assertTrue(t instanceof DataException);
57
+ }
58
+ }
59
+
60
+ @Test
61
+ public void asBooleanFromFloat()
62
+ {
63
+ try {
64
+ ColumnCaster.asBoolean(ValueFactory.newFloat(1.1));
65
+ fail();
66
+ }
67
+ catch (Throwable t) {
68
+ assertTrue(t instanceof DataException);
69
+ }
70
+ }
71
+
72
+ @Test
73
+ public void asBooleanFromString()
74
+ {
75
+ assertEquals(true, ColumnCaster.asBoolean(ValueFactory.newString("true")));
76
+ try {
77
+ ColumnCaster.asBoolean(ValueFactory.newString("foo"));
78
+ fail();
79
+ }
80
+ catch (Throwable t) {
81
+ assertTrue(t instanceof DataException);
82
+ }
83
+ }
84
+
85
+ @Test
86
+ public void asBooleanFromJson()
87
+ {
88
+ try {
89
+ ColumnCaster.asBoolean(mapValue);
90
+ fail();
91
+ }
92
+ catch (Throwable t) {
93
+ assertTrue(t instanceof DataException);
94
+ }
95
+ }
96
+
97
+ @Test
98
+ public void asLongFromBoolean()
99
+ {
100
+ assertEquals(1, ColumnCaster.asLong(ValueFactory.newBoolean(true)));
101
+ }
102
+
103
+ @Test
104
+ public void asLongFromInteger()
105
+ {
106
+ assertEquals(1, ColumnCaster.asLong(ValueFactory.newInteger(1)));
107
+ }
108
+
109
+ @Test
110
+ public void asLongFromFloat()
111
+ {
112
+ assertEquals(1, ColumnCaster.asLong(ValueFactory.newFloat(1.5)));
113
+ }
114
+
115
+ @Test
116
+ public void asLongFromString()
117
+ {
118
+ assertEquals(1, ColumnCaster.asLong(ValueFactory.newString("1")));
119
+ try {
120
+ ColumnCaster.asLong(ValueFactory.newString("foo"));
121
+ fail();
122
+ }
123
+ catch (Throwable t) {
124
+ assertTrue(t instanceof DataException);
125
+ }
126
+ }
127
+
128
+ @Test
129
+ public void asLongFromJson()
130
+ {
131
+ try {
132
+ ColumnCaster.asLong(mapValue);
133
+ fail();
134
+ }
135
+ catch (Throwable t) {
136
+ assertTrue(t instanceof DataException);
137
+ }
138
+ }
139
+
140
+ @Test
141
+ public void asDoubleFromBoolean()
142
+ {
143
+ assertEquals(1, ColumnCaster.asLong(ValueFactory.newBoolean(true)));
144
+ }
145
+
146
+ @Test
147
+ public void asDoubleFromInteger()
148
+ {
149
+ assertEquals(1, ColumnCaster.asLong(ValueFactory.newInteger(1)));
150
+ }
151
+
152
+ @Test
153
+ public void asDoubleFromFloat()
154
+ {
155
+ assertEquals(1, ColumnCaster.asLong(ValueFactory.newFloat(1.5)));
156
+ }
157
+
158
+ @Test
159
+ public void asDoubleFromString()
160
+ {
161
+ assertEquals(1, ColumnCaster.asLong(ValueFactory.newString("1")));
162
+ try {
163
+ ColumnCaster.asLong(ValueFactory.newString("foo"));
164
+ fail();
165
+ }
166
+ catch (Throwable t) {
167
+ assertTrue(t instanceof DataException);
168
+ }
169
+ }
170
+
171
+ @Test
172
+ public void asDoubleFromJson()
173
+ {
174
+ try {
175
+ ColumnCaster.asLong(mapValue);
176
+ fail();
177
+ }
178
+ catch (Throwable t) {
179
+ assertTrue(t instanceof DataException);
180
+ }
181
+ }
182
+
183
+ @Test
184
+ public void asStringFromBoolean()
185
+ {
186
+ assertEquals("true", ColumnCaster.asString(ValueFactory.newBoolean(true)));
187
+ }
188
+
189
+ @Test
190
+ public void asStringFromInteger()
191
+ {
192
+ assertEquals("1", ColumnCaster.asString(ValueFactory.newInteger(1)));
193
+ }
194
+
195
+ @Test
196
+ public void asStringFromFloat()
197
+ {
198
+ assertEquals("1.5", ColumnCaster.asString(ValueFactory.newFloat(1.5)));
199
+ }
200
+
201
+ @Test
202
+ public void asStringFromString()
203
+ {
204
+ assertEquals("1", ColumnCaster.asString(ValueFactory.newString("1")));
205
+ }
206
+
207
+ @Test
208
+ public void asStringFromJson()
209
+ {
210
+ assertEquals("{\"k\":\"v\"}", ColumnCaster.asString(mapValue));
211
+ }
212
+
213
+ @Test
214
+ public void asTimestampFromBoolean()
215
+ {
216
+ try {
217
+ ColumnCaster.asTimestamp(ValueFactory.newBoolean(true), parser);
218
+ fail();
219
+ }
220
+ catch (Throwable t) {
221
+ assertTrue(t instanceof DataException);
222
+ }
223
+ }
224
+
225
+ @Test
226
+ public void asTimestampFromInteger()
227
+ {
228
+ assertEquals(1, ColumnCaster.asTimestamp(ValueFactory.newInteger(1), parser).getEpochSecond());
229
+ }
230
+
231
+ @Test
232
+ public void asTimestampFromFloat()
233
+ {
234
+ Timestamp expected = Timestamp.ofEpochSecond(1463084053, 500000000);
235
+ assertEquals(expected, ColumnCaster.asTimestamp(ValueFactory.newFloat(1463084053.5), parser));
236
+ }
237
+
238
+ @Test
239
+ public void asTimestampFromString()
240
+ {
241
+ Timestamp expected = Timestamp.ofEpochSecond(1463084053, 500000000);
242
+ assertEquals(expected, ColumnCaster.asTimestamp(ValueFactory.newString("2016-05-12 20:14:13.5"), parser));
243
+ }
244
+
245
+ @Test
246
+ public void asTimestampFromJson()
247
+ {
248
+ try {
249
+ ColumnCaster.asTimestamp(mapValue, parser);
250
+ fail();
251
+ }
252
+ catch (Throwable t) {
253
+ assertTrue(t instanceof DataException);
254
+ }
255
+ }
256
+ }