activecube-graphql 0.1.26 → 0.1.27

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d28651611a3435fe0b0f85a8305d5b9b71fca9fbf48e7baffe055ee13ebc0762
4
- data.tar.gz: 46af8b29f6594cb934c638dc32715d8e9b707652286032144725ce4d127ba6ca
3
+ metadata.gz: 427eb4f80127a71beec9aeb9d15e728055d606b3487c4029ade46a64362d186d
4
+ data.tar.gz: b2736abe51d04a48ad92be0d96d8ac7b4bd198c51031e7143333ec56058a7c5b
5
5
  SHA512:
6
- metadata.gz: b9aa58663c3966927e879de34ec4690b790cc143a72087db20c6a73b7803f5b63b4da8c6e82654c3076e317abbe9592c9c31f30409c226a5c118f8f525bc02cd
7
- data.tar.gz: a7128035f399bbbf6090201796c39781895e9572e6bee6de680b17760375a92f3eea26a4015192b6407c95842feb11deaaaf49f1802f7edb05239d1c0222ed86
6
+ metadata.gz: 020c246afeefa93a9596f20d3b8006bbdafb8775ea628b08be0188b9babc367be862996ea40b99a3b6741647ad6bc0c3b539e79befe879b4b4c5b0bbb39dcb6a
7
+ data.tar.gz: e2322a5cf3ce5c9104fb5d767580a714a01624ed2db9148f3280c1f04c093c188881ae9bb789b8a616cc54103f67b2518995afe1b85d82ecbc37aa9ddecd7597
@@ -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
 
@@ -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.26"
3
+ VERSION = "0.1.27"
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.26
4
+ version: 0.1.27
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-02-10 00:00:00.000000000 Z
11
+ date: 2022-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activecube