1
1
package org .polars .scala .polars .api .types
2
2
3
- import java .time .ZoneId
4
- import java .util .Locale
5
- import java .util .concurrent .TimeUnit
6
-
7
3
import scala .jdk .CollectionConverters ._
8
4
import scala .util .Try
9
5
@@ -52,40 +48,54 @@ class Schema private (private[polars] val json: String) {
52
48
case (name, node, _ @ JsonNodeType .STRING ) =>
53
49
Field (name, DataType .fromBasicType(node.textValue()))
54
50
51
+ // For Time Type
52
+ case (name, node, _ @ JsonNodeType .OBJECT )
53
+ if node.hasNonNull(" Time" ) || node.hasNonNull(" Time32" ) || node.hasNonNull(" Time64" ) =>
54
+ Seq (node.get(" Time" ), node.get(" Time32" ), node.get(" Time64" ))
55
+ .map(Option (_))
56
+ .collectFirst { case Some (v) => v } match {
57
+ case Some (timeUnit) => Field (name, TimeType (timeUnit.textValue()))
58
+
59
+ case None =>
60
+ throw new IllegalArgumentException (" Invalid time cannot be parsed." )
61
+ }
62
+
63
+ // For Duration Type
64
+ case (name, node, _ @ JsonNodeType .OBJECT ) if node.hasNonNull(" Duration" ) =>
65
+ val timeUnit = node.get(" Duration" )
66
+ Field (name, Duration (timeUnit.textValue()))
67
+
55
68
// For DateTime Type
56
- case (name, node, _ @ JsonNodeType .OBJECT ) if node.has(" Datetime" ) =>
57
- // todo: validate the timeunit and timezone and re-enable this later
58
-
59
- // val dtNode = node.get("Datetime")
60
- //
61
- // val (tu, tz) = dtNode.iterator().asScala.map(_.textValue()).toSeq match {
62
- // case Seq(null, null) =>
63
- // (TimeUnit.MICROSECONDS, ZoneId.of("UTC"))
64
- // case Seq(null, tz) if tz.nonEmpty =>
65
- // (TimeUnit.MICROSECONDS, ZoneId.of(tz))
66
- // case Seq(tu, null) if tu.nonEmpty =>
67
- // (TimeUnit.valueOf(tu.toUpperCase(Locale.ROOT)), ZoneId.of("UTC"))
68
- // case Seq(tu, tz) if tu.nonEmpty && tz.nonEmpty =>
69
- // (TimeUnit.valueOf(tu.toUpperCase(Locale.ROOT)), ZoneId.of(tz))
70
- // case _ =>
71
- // (TimeUnit.MICROSECONDS, ZoneId.of("UTC"))
72
- // }
73
-
74
- Field (name, DateTimeType )
69
+ case (name, node, _ @ JsonNodeType .OBJECT ) if node.hasNonNull(" Timestamp" ) =>
70
+ node.get(" Timestamp" ).elements().asScala.map(_.asText(null )).toSeq match {
71
+ case Seq (tu, tz) =>
72
+ Field (name, DateTimeType (tu, tz))
73
+ case _ =>
74
+ Field (name, DateTimeType (null , null ))
75
+ }
75
76
76
77
// For (Nested) List Type
77
- case (name, node, _ @ JsonNodeType .OBJECT ) if node.has(" List" ) =>
78
- val listNode = node.get(" List" )
79
- Field (name, ListType (toField((name, listNode, listNode.getNodeType)).dataType))
78
+ case (name, node, _ @ JsonNodeType .OBJECT )
79
+ if node.hasNonNull(" List" ) || node.hasNonNull(" LargeList" ) =>
80
+ Seq (node.get(" List" ), node.get(" LargeList" ))
81
+ .map(Option (_))
82
+ .collectFirst { case Some (v) => v } match {
83
+ case Some (listNode) =>
84
+ val listNodeType = listNode.get(" data_type" )
85
+ Field (name, ListType (toField((name, listNodeType, listNodeType.getNodeType)).dataType))
86
+
87
+ case None =>
88
+ throw new IllegalArgumentException (" Invalid list cannot be parsed as a JSON." )
89
+ }
80
90
81
91
// For (Nested) Struct Type
82
92
case (name, node, _ @ JsonNodeType .OBJECT ) if node.has(" Struct" ) =>
83
93
val structNode = node.get(" Struct" )
84
94
val structFields = structNode.iterator().asScala
85
95
val sf = structFields.map {
86
- case node : JsonNode if node.fieldNames().asScala.toSet == Set ( " name " , " dtype " ) =>
96
+ case node : JsonNode if node.hasNonNull( " name " ) && node.hasNonNull( " data_type " ) =>
87
97
val structFieldName : String = node.get(" name" ).textValue()
88
- val structFieldType : JsonNode = node.get(" dtype " )
98
+ val structFieldType : JsonNode = node.get(" data_type " )
89
99
90
100
Field (
91
101
structFieldName,
@@ -106,10 +116,14 @@ class Schema private (private[polars] val json: String) {
106
116
case None =>
107
117
throw new IllegalArgumentException (" Provided schema string cannot be parsed as a JSON." )
108
118
109
- case Some (node : JsonNode ) if node.has(" inner" ) =>
110
- val fields = node.get(" inner" ).fields().asScala
111
- _fields = fields.map(f => toField(f.getKey, f.getValue, f.getValue.getNodeType)).toArray
112
- _fieldNames = node.fieldNames().asScala.toArray
119
+ case Some (node : JsonNode ) if node.hasNonNull(" fields" ) =>
120
+ val fields = node.get(" fields" ).elements().asScala.toList
121
+ _fields = fields
122
+ .map(f =>
123
+ toField(f.get(" name" ).textValue(), f.get(" data_type" ), f.get(" data_type" ).getNodeType)
124
+ )
125
+ .toArray
126
+ _fieldNames = fields.map(f => f.get(" name" ).toString).toArray
113
127
114
128
case _ =>
115
129
throw new IllegalArgumentException (" Provided schema string is an invalid JSON." )
0 commit comments