trino-client 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ChangeLog.md +4 -0
- data/lib/trino/client/column_value_parser.rb +115 -0
- data/lib/trino/client/query.rb +28 -0
- data/lib/trino/client/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 887c8e77f79998cb038d93f27879b2ca268d455343cb4628b865306ba894ab1d
|
4
|
+
data.tar.gz: 2f28c84bc26e36da9de4f5b3d275d099ecd304341f6640bd75c973fd8d14eded
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34c0baa8b9f349abc713cb1ddfcd639d04a755308c8836a504fe6e58b62992f5cea14c34e8df3d29ae0351770550519aaf3d70f12ba8a63b5a8d28ffec463dc4
|
7
|
+
data.tar.gz: fd12c7387e02b80911b2a1f6f95e68fa2e4ce798b3dea762c9097d9809847993840d424a4b47a95e62bf1ff6649294649ec184065beb83b86f12b5ba2a655900
|
data/ChangeLog.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
trino-client-ruby
|
2
2
|
====
|
3
|
+
## 2.1.0
|
4
|
+
- Add utility for transforming Trino ROW type columns into Ruby hashes ([#117](https://github.com/treasure-data/trino-client-ruby/issues/117)) [[e14251c](https://github.com/treasure-data/trino-client-ruby/commit/e14251c)]
|
5
|
+
- Bump actions/checkout from 3 to 4 ([#116](https://github.com/treasure-data/trino-client-ruby/issues/116)) [[ebd9d9e](https://github.com/treasure-data/trino-client-ruby/commit/ebd9d9e)]
|
6
|
+
|
3
7
|
## 2.0.1
|
4
8
|
- Reduce published gem size ([#113](https://github.com/treasure-data/trino-client-ruby/issues/113)) [[4e03819](https://github.com/treasure-data/trino-client-ruby/commit/4e03819)]
|
5
9
|
- Update standard requirement from ~> 1.24.3 to ~> 1.30.1 ([#112](https://github.com/treasure-data/trino-client-ruby/issues/112)) [[b9f9c0c](https://github.com/treasure-data/trino-client-ruby/commit/b9f9c0c)]
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Trino::Client
|
2
|
+
class ColumnValueParser
|
3
|
+
INSIDE_MATCHING_PARENS_REGEX = /\((?>[^)(]+|\g<0>)*\)/
|
4
|
+
|
5
|
+
attr_reader :name, :type, :scalar_parser
|
6
|
+
|
7
|
+
def initialize(column, scalar_parser = nil)
|
8
|
+
@name = column.name
|
9
|
+
@type = prepare_type_for_parsing(column.type)
|
10
|
+
@scalar_parser = scalar_parser
|
11
|
+
end
|
12
|
+
|
13
|
+
# Public: Parse the value of a row's field by using its column's Trino type.
|
14
|
+
# Trino types can be scalars like VARCHAR and TIMESTAMP or complex types
|
15
|
+
# like ARRAY and ROW. ROW types are treated as objects.
|
16
|
+
# An ARRAY column's type is an array of types as you'd expect. A ROW
|
17
|
+
# column's type is a comma-separated list of space-separated (name, type) tuples.
|
18
|
+
#
|
19
|
+
# data - The value of a row's field. Can be a string, number, an array of those,
|
20
|
+
# or an arrays of arrays, etc.
|
21
|
+
# dtype - The Trino type string of the column. See above explanation.
|
22
|
+
#
|
23
|
+
# Returns:
|
24
|
+
# - The given value for strings and numbers
|
25
|
+
# - A Time for timestamps
|
26
|
+
# - A Hash of { field1 => value1, field2 => value2, ...etc } for row types
|
27
|
+
# - An array of the above for array types
|
28
|
+
def value(data, dtype = type)
|
29
|
+
# Convert Trino ARRAY elements into Ruby Arrays
|
30
|
+
if starts_with?(dtype, 'array(')
|
31
|
+
return parse_array_element(data, dtype)
|
32
|
+
|
33
|
+
# Convert Trino ROW elements into Ruby Hashes
|
34
|
+
elsif starts_with?(dtype, 'row(')
|
35
|
+
return parse_row_element(data, dtype)
|
36
|
+
|
37
|
+
# If defined, use scalar_parser to convert scalar types
|
38
|
+
elsif !scalar_parser.nil?
|
39
|
+
return scalar_parser.call(data, dtype)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Otherwise, values are returned unaltered
|
43
|
+
data
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Private: Remove quotation marks and handle recent versions of
|
49
|
+
# Trino having a 'with time zone' suffix on some fields that breaks
|
50
|
+
# out assumption that types don't have spaces in them.
|
51
|
+
#
|
52
|
+
# Returns a string.
|
53
|
+
def prepare_type_for_parsing(type)
|
54
|
+
type.gsub('"', '').gsub(' with time zone', '_with_time_zone')
|
55
|
+
end
|
56
|
+
|
57
|
+
def parse_array_element(data, dtype)
|
58
|
+
# If the element is empty, return an empty array
|
59
|
+
return [] if blank?(data)
|
60
|
+
|
61
|
+
# Inner data type will be the current dtype with `array(` and `)` chopped off
|
62
|
+
inner_dtype = dtype.match(INSIDE_MATCHING_PARENS_REGEX)[0][1..-2]
|
63
|
+
|
64
|
+
data.map { |inner_data| value(inner_data, inner_dtype) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def parse_row_element(data, dtype)
|
68
|
+
# If the element is empty, return an empty object
|
69
|
+
return {} if blank?(data)
|
70
|
+
|
71
|
+
parsed_row_element = {}
|
72
|
+
|
73
|
+
inner_dtype = dtype.match(INSIDE_MATCHING_PARENS_REGEX)[0][1..-2]
|
74
|
+
elems = inner_dtype.split(' ')
|
75
|
+
num_elems_to_skip = 0
|
76
|
+
field_position = 0
|
77
|
+
|
78
|
+
# Iterate over each datatype of the row and mutate parsed_row_element
|
79
|
+
# to have a key of the field name and value for that field's value.
|
80
|
+
elems.each_with_index do |field, i|
|
81
|
+
# We detected an array or row and are skipping all of the elements within it
|
82
|
+
# since its conversion was handled by calling `value` recursively.
|
83
|
+
if num_elems_to_skip.positive?
|
84
|
+
num_elems_to_skip -= 1
|
85
|
+
next
|
86
|
+
end
|
87
|
+
|
88
|
+
# Field names never have these characters and are never the last element.
|
89
|
+
next if field.include?(',') || field.include?('(') || field.include?(')') || i == elems.length - 1
|
90
|
+
|
91
|
+
type = elems[(i + 1)..].join(' ')
|
92
|
+
|
93
|
+
# If this row has a nested array or row, the type of this field is that array or row's type.
|
94
|
+
if starts_with?(type, 'array(') || starts_with?(type, 'row(')
|
95
|
+
datatype = type.sub(/\(.*/, '')
|
96
|
+
type = "#{datatype}#{type.match(INSIDE_MATCHING_PARENS_REGEX)[0]}"
|
97
|
+
num_elems_to_skip = type.split(' ').length # see above comment about num_elems_to_skip
|
98
|
+
end
|
99
|
+
|
100
|
+
parsed_row_element[field] = value(data[field_position], type)
|
101
|
+
field_position += 1
|
102
|
+
end
|
103
|
+
|
104
|
+
parsed_row_element
|
105
|
+
end
|
106
|
+
|
107
|
+
def blank?(obj)
|
108
|
+
obj.respond_to?(:empty?) ? !!obj.empty? : !obj
|
109
|
+
end
|
110
|
+
|
111
|
+
def starts_with?(str, prefix)
|
112
|
+
prefix.respond_to?(:to_str) && str[0, prefix.length] == prefix
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/lib/trino/client/query.rb
CHANGED
@@ -18,6 +18,7 @@ module Trino::Client
|
|
18
18
|
require 'faraday'
|
19
19
|
require 'faraday/gzip'
|
20
20
|
require 'faraday/follow_redirects'
|
21
|
+
require 'trino/client/column_value_parser'
|
21
22
|
require 'trino/client/models'
|
22
23
|
require 'trino/client/errors'
|
23
24
|
require 'trino/client/faraday_client'
|
@@ -44,6 +45,19 @@ module Trino::Client
|
|
44
45
|
Trino::Client.faraday_client(options)
|
45
46
|
end
|
46
47
|
|
48
|
+
def self.transform_row(column_value_parsers, row)
|
49
|
+
row_object = {}
|
50
|
+
|
51
|
+
row.each_with_index do |element, i|
|
52
|
+
column = column_value_parsers[i]
|
53
|
+
value = column.value(element)
|
54
|
+
|
55
|
+
row_object[column.name] = value
|
56
|
+
end
|
57
|
+
|
58
|
+
row_object
|
59
|
+
end
|
60
|
+
|
47
61
|
def initialize(api)
|
48
62
|
@api = api
|
49
63
|
end
|
@@ -86,6 +100,20 @@ module Trino::Client
|
|
86
100
|
return @api.current_results.columns
|
87
101
|
end
|
88
102
|
|
103
|
+
def column_value_parsers
|
104
|
+
@column_value_parsers ||= columns.map {|column|
|
105
|
+
ColumnValueParser.new(column)
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
def transform_rows
|
110
|
+
rows.map(&:transform_row)
|
111
|
+
end
|
112
|
+
|
113
|
+
def transform_row(row)
|
114
|
+
self.class.transform_row(column_value_parsers, row)
|
115
|
+
end
|
116
|
+
|
89
117
|
def rows
|
90
118
|
rows = []
|
91
119
|
each_row_chunk {|chunk|
|
data/lib/trino/client/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trino-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -190,6 +190,7 @@ files:
|
|
190
190
|
- lib/trino-client.rb
|
191
191
|
- lib/trino/client.rb
|
192
192
|
- lib/trino/client/client.rb
|
193
|
+
- lib/trino/client/column_value_parser.rb
|
193
194
|
- lib/trino/client/errors.rb
|
194
195
|
- lib/trino/client/faraday_client.rb
|
195
196
|
- lib/trino/client/model_versions/0.149.rb
|