activecube-graphql 0.1.25 → 0.1.28

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2e6172c07df1e643e9bc1f37d505e3ccc31e58cfd1741ee37850eba6ffc6dfb
4
- data.tar.gz: b6aab3e06f0d78cfc455b1e834f93b0f79d411e93127da6983444297b8ebb3b0
3
+ metadata.gz: 5388716d32a65066a03ff46e088d03ea333bb61d43c9630e48e0441f2a6ff8c8
4
+ data.tar.gz: 5f8eaff96b4d8424d248118cbcfcd2f5922a55f901e833bfbdae5c4e6e0f1667
5
5
  SHA512:
6
- metadata.gz: 633d43b3712caafd333bd12aafb953ad9f02c9aa0b904bac7a7d6f4271dbe36c01af9a5a638dcc0174ed8f610af4dda70c2f6f9950283f97fe5b2fa7b86709ff
7
- data.tar.gz: c88d7d9910fb014e558019e34f964143e0631bcf9cb07b3dae7f0df3f898db994d1cd55cb7308f5395f55b85ee7887b7e5942f628e5d5fe59a53411c92217706
6
+ metadata.gz: 2adec53fd1eb35a284454ba5776435111b4c2f1762da3f251dee1986e046f441436f37eba468c7fb4c91ee11316821c025a2d7e3d2bd13495020cae80c39afb1
7
+ data.tar.gz: 965542f1e000bb11167015c1b2f0614e58122583c134f46523175b18aa69eee8aaa8b2b0be454168986e6c6ce97a7aa6ba68ca0f1aa90113b478e2b367ce7b5a
@@ -48,12 +48,7 @@ module Activecube
48
48
  def execute_query tree, ctx, object
49
49
  cube_query = tree.build_query
50
50
  cube_query = object.append_cube_query(cube_query) if object.respond_to?(:append_cube_query)
51
-
52
- stats = ctx[:stats]
53
- cube_query.stats = stats
54
-
55
- sql_io = stats.sql_io
56
- sql_io.puts(cube_query.to_sql) if sql_io.respond_to?(:puts)
51
+ cube_query.stats = ctx[:stats]
57
52
  cube_query.query
58
53
  end
59
54
 
@@ -8,21 +8,19 @@ module Activecube
8
8
  KEY_FIELD_PREFIX = '_aq.'
9
9
  NULLABLE_OPERATORS = [:eq,:not_eq,:is,:not]
10
10
 
11
- attr_reader :arguments, :ast_node, :cube, :parent, :name, :definition, :key,
12
- :children, :metric, :dimension, :field, :context_node
11
+ attr_reader :arguments, :cube, :parent, :name, :definition, :key,
12
+ :children, :metric, :dimension, :field, :type_name
13
+
13
14
  def initialize cube, context_node, parent = nil
14
15
 
15
16
  @cube = cube
16
17
  @parent = parent
18
+ @type_name = context_node.definition.type.try(:of_type).try(:name) || context_node.definition.type.try(:name)
17
19
 
18
20
  @name = context_node.name
19
21
  @key = parent ? (parent.key ? "#{parent.key}.#{name}" : KEY_FIELD_PREFIX+name ) : nil
20
22
 
21
- @context_node = context_node
22
- @ast_node = context_node.ast_node
23
-
24
- @arguments = sort_node_arguments ast_node, context_node.arguments.to_h
25
-
23
+ @arguments = sort_node_arguments context_node
26
24
 
27
25
  if parent
28
26
  @definition = context_node.definitions.first.name
@@ -38,14 +36,15 @@ module Activecube
38
36
  end
39
37
 
40
38
  @children = context_node.typed_children.values.map(&:values).flatten.uniq(&:name).
41
- select{|child| child.name!=TYPENAME || union? }.
39
+ select{|child| child.name!=TYPENAME || union?(context_node) }.
42
40
  collect do |child|
43
41
  Element.new cube, child, self
44
42
  end
45
43
 
46
44
  end
47
45
 
48
- def sort_node_arguments ast_node, arguments
46
+ def sort_node_arguments context_node
47
+ arguments = context_node.arguments.to_h
49
48
  if (options = arguments['options']).kind_of?(Hash)
50
49
  if opt_keys_args = context_node.ast_node.arguments.detect{|x| x.name=='options'}.value.try(:arguments)
51
50
  options_keys = opt_keys_args.map{|x|
@@ -68,10 +67,20 @@ module Activecube
68
67
  arguments
69
68
  end
70
69
 
71
- def union?
70
+ def union? context_node
72
71
  context_node.return_type.kind_of? GraphQL::UnionType
73
72
  end
74
73
 
74
+ def as_json options = {}
75
+ {
76
+ cube: cube.name,
77
+ name: name,
78
+ definition: definition,
79
+ key: key,
80
+ children: children
81
+ }
82
+ end
83
+
75
84
  def append_query query
76
85
  if parent
77
86
 
@@ -126,7 +135,7 @@ module Activecube
126
135
 
127
136
  def converted_field_array method, values
128
137
  case method
129
- when :desc,:asc
138
+ when :desc, :desc_by_integer, :asc, :asc_by_integer
130
139
  values.collect{|v| KEY_FIELD_PREFIX + v}
131
140
  when :limit_by
132
141
  values.merge({each: KEY_FIELD_PREFIX + values[:each]})
@@ -9,8 +9,8 @@ module Activecube::Graphql
9
9
  @row = row
10
10
  end
11
11
 
12
- def convert_type node_type, value
13
- case node_type
12
+ def convert_type type_name, value
13
+ case type_name
14
14
  when 'Boolean' then
15
15
  value==1
16
16
  else
@@ -24,125 +24,135 @@ module Activecube::Graphql
24
24
 
25
25
  end
26
26
 
27
+ class ResponseClassRegistry
27
28
 
28
- attr_reader :response, :response_class
29
- def initialize tree, response
30
- @response = response
31
- @key_map = Hash[response.columns.map.with_index{|key,index| [key, index]}]
32
- @response_class = build_response_class tree.root
33
- end
29
+ include Singleton
34
30
 
35
- def map &block
36
- raise Activecube::InputArgumentError, "Block expected on map of root response" unless block_given?
37
- response.rows.map do |row|
38
- block.call response_class.new row
31
+ def initialize
32
+ @registry = {}
39
33
  end
40
- end
41
34
 
42
- def build_response_class from_element
35
+ def get_response_class element, key_map
36
+ key = element.to_json + key_map.to_json
37
+ @registry[key] ||= build_response_class(element,key_map)
38
+ end
39
+
40
+ def build_response_class from_element, key_map
43
41
 
44
- response_class = Class.new Response
42
+ response_class = Class.new Response
45
43
 
46
- from_element.children.group_by(&:definition).each{|definition, elements|
44
+ from_element.children.group_by(&:definition).each{|definition, elements|
47
45
 
48
- if elements.count==1
49
- element = elements.first
50
- if element.children.empty?
51
- simple_value response_class, definition, element
52
- elsif element.metric
53
- array_value response_class, definition, element
46
+ if elements.count==1
47
+ element = elements.first
48
+ if element.children.empty?
49
+ simple_value response_class, definition, element, key_map
50
+ elsif element.metric
51
+ array_value response_class, definition, element, key_map
52
+ else
53
+ sub_element response_class, definition, element, key_map
54
+ end
54
55
  else
55
- sub_element response_class, definition, element
56
+ match_elements response_class, definition, elements, key_map
56
57
  end
57
- else
58
- match_elements response_class, definition, elements
59
- end
60
58
 
61
- }
59
+ }
62
60
 
63
- response_class
61
+ response_class
64
62
 
65
- end
63
+ end
66
64
 
67
- private
68
-
69
- def match_elements response_class, definition, elements
70
-
71
- index = Hash[elements.collect { |element|
72
- value = if element.children.empty?
73
- [@key_map[element.key], element.context_node.definition.type.name]
74
- else
75
- build_response_class element
76
- end
77
- [element.name, value]
78
- }]
79
-
80
- response_class.class_eval do
81
- define_method definition.underscore do |ast_node:, **rest_of_options|
82
- key = ast_node.alias || ast_node.name
83
- if (value = index[key]).kind_of? Class
84
- value.new @row
85
- elsif value.kind_of? Array
86
- convert_type value.second, @row[value.first]
87
- else
88
- raise Activecube::InputArgumentError, "Unexpected request to #{definition} by key #{key}"
65
+
66
+ def match_elements response_class, definition, elements, key_map
67
+
68
+ index = Hash[elements.collect { |element|
69
+ value = if element.children.empty?
70
+ [key_map[element.key], element.type_name]
71
+ else
72
+ get_response_class element, key_map
73
+ end
74
+ [element.name, value]
75
+ }]
76
+
77
+ response_class.class_eval do
78
+ define_method definition.underscore do |ast_node:, **rest_of_options|
79
+ key = ast_node.alias || ast_node.name
80
+ if (value = index[key]).kind_of? Class
81
+ value.new @row
82
+ elsif value.kind_of? Array
83
+ convert_type value.second, @row[value.first]
84
+ else
85
+ raise Activecube::InputArgumentError, "Unexpected request to #{definition} by key #{key}"
86
+ end
89
87
  end
90
88
  end
91
- end
92
89
 
93
- end
90
+ end
94
91
 
95
- def sub_element response_class, definition, element
96
- subclass = build_response_class element
97
- response_class.class_eval do
98
- define_method definition.underscore do |**rest_of_options|
99
- subclass.new @row
92
+ def sub_element response_class, definition, element, key_map
93
+ subclass = get_response_class element, key_map
94
+ response_class.class_eval do
95
+ define_method definition.underscore do |**rest_of_options|
96
+ subclass.new @row
97
+ end
100
98
  end
101
99
  end
102
- end
103
-
104
- def node_type element
105
- element.context_node.definition.type.try(:of_type).try(:name) || element.context_node.definition.type.try(:name)
106
- end
107
100
 
108
- def simple_value response_class, definition, element
109
- index = @key_map[element.key]
110
- node_type = node_type element
111
- response_class.class_eval do
112
- define_method definition.underscore do |**rest_of_options|
113
- convert_type node_type, @row[index]
101
+ def simple_value response_class, definition, element, key_map
102
+ index = key_map[element.key]
103
+ type_name = element.type_name
104
+ response_class.class_eval do
105
+ define_method definition.underscore do |**rest_of_options|
106
+ convert_type type_name, @row[index]
107
+ end
114
108
  end
115
109
  end
116
- end
117
110
 
118
- def array_value response_class, definition, element
119
- index = @key_map[element.key]
120
- array_element_type = if element.children.empty?
121
- node_type element
122
- else
123
- tuple = element.metric.definition.class.tuple
124
- element.children.collect{|a| [ a.name, node_type(a), tuple.index(a.name.to_sym)] }
125
- end
126
-
127
- response_class.class_eval do
128
- define_method definition.underscore do |**rest_of_options|
129
- @row[index].map{|array_obj|
130
- if array_obj.kind_of?(Array) && array_element_type.kind_of?(Array)
131
- Hash[
111
+ def array_value response_class, definition, element, key_map
112
+ index = key_map[element.key]
113
+ array_element_type = if element.children.empty?
114
+ element.type_name
115
+ else
116
+ tuple = element.metric.definition.class.tuple
117
+ element.children.collect{|a| [ a.name, a.type_name, tuple.index(a.name.to_sym)] }
118
+ end
119
+
120
+ response_class.class_eval do
121
+ define_method definition.underscore do |**rest_of_options|
122
+ @row[index].map{|array_obj|
123
+ if array_obj.kind_of?(Array) && array_element_type.kind_of?(Array)
124
+ Hash[
132
125
  array_element_type.map{|etype|
133
126
  [etype.first.underscore, convert_type(etype.second, array_obj[etype.third])]
134
127
  }]
135
- elsif !array_obj.kind_of?(Array) && array_element_type.kind_of?(String)
136
- convert_type(array_element_type, obj)
137
- else
138
- raise "Mismatched data in #{array_obj} with #{array_element_type} for #{definition} of #{element.key}"
139
- end
140
- }
128
+ elsif !array_obj.kind_of?(Array) && array_element_type.kind_of?(String)
129
+ convert_type(array_element_type, obj)
130
+ else
131
+ raise "Mismatched data in #{array_obj} with #{array_element_type} for #{definition} of #{element.key}"
132
+ end
133
+ }
134
+ end
141
135
  end
136
+
137
+
142
138
  end
143
139
 
140
+ end
144
141
 
142
+ attr_reader :response, :response_class
143
+ def initialize tree, response
144
+ @response = response
145
+ key_map = Hash[response.columns.map.with_index{|key,index| [key, index]}]
146
+ @response_class = ResponseClassRegistry.instance.get_response_class tree.root, key_map
145
147
  end
146
148
 
149
+ def map &block
150
+ raise Activecube::InputArgumentError, "Block expected on map of root response" unless block_given?
151
+ response.rows.map do |row|
152
+ block.call response_class.new row
153
+ end
154
+ end
155
+
156
+
147
157
  end
148
158
  end
@@ -1,5 +1,5 @@
1
1
  module Activecube
2
2
  module Graphql
3
- VERSION = "0.1.25"
3
+ VERSION = "0.1.28"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activecube-graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.25
4
+ version: 0.1.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleksey Studnev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-18 00:00:00.000000000 Z
11
+ date: 2022-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activecube