activecube-graphql 0.1.22 → 0.1.27

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: 9ff3d9f5f10865d312810addf9b8b2b02d5e1da42bfb450c6b6a2d1c6c245720
4
- data.tar.gz: 958384371784f96feeddce3d9e3219bd6355138939d11c7e6be49810e5eea98a
3
+ metadata.gz: 427eb4f80127a71beec9aeb9d15e728055d606b3487c4029ade46a64362d186d
4
+ data.tar.gz: b2736abe51d04a48ad92be0d96d8ac7b4bd198c51031e7143333ec56058a7c5b
5
5
  SHA512:
6
- metadata.gz: 50a5432f0a2d372b4ee9ae646675c79c6e2e42dddc0b68dc06147308fa995f18bde07b3d8d29f094f734acb73010945d86c822d346248e8f9fbf20fb923eff03
7
- data.tar.gz: 7a51f2c654add24b517266bd6de37d7e96fce3f4b298fd026959f23c163e972c00733fe2c5a7054757ec8c1fc3604026836654249e401024c2a1fac1170d2805
6
+ metadata.gz: 020c246afeefa93a9596f20d3b8006bbdafb8775ea628b08be0188b9babc367be862996ea40b99a3b6741647ad6bc0c3b539e79befe879b4b4c5b0bbb39dcb6a
7
+ data.tar.gz: e2322a5cf3ce5c9104fb5d767580a714a01624ed2db9148f3280c1f04c093c188881ae9bb789b8a616cc54103f67b2518995afe1b85d82ecbc37aa9ddecd7597
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- activecube-graphql (0.1.21)
4
+ activecube-graphql (0.1.22)
5
5
  activecube (~> 0.1.28)
6
6
  graphql (~> 1.10)
7
7
 
@@ -34,12 +34,8 @@ module Activecube
34
34
  (object.respond_to?(:database) && object.database)
35
35
 
36
36
  response = database ? cube.connected_to(database: database) do
37
- execute_query(tree, ctx)
38
- end : execute_query(tree, ctx)
39
-
40
- if ctx[:stat_io].respond_to?(:puts) && response.respond_to?(:statistics)
41
- ctx[:stat_io].puts(response.statistics)
42
- end
37
+ execute_query(tree, ctx, object)
38
+ end : execute_query(tree, ctx, object)
43
39
 
44
40
  ResponseBuilder.new tree, response
45
41
 
@@ -49,11 +45,10 @@ module Activecube
49
45
 
50
46
  private
51
47
 
52
- def execute_query tree, ctx
48
+ def execute_query tree, ctx, object
53
49
  cube_query = tree.build_query
54
- cube_query.user_agent = ctx[:sql_user_agent] || 'Ruby/Activecube Graphql'
55
-
56
- ctx[:sql_io].puts(cube_query.to_sql) if ctx[:sql_io].respond_to?(:puts)
50
+ cube_query = object.append_cube_query(cube_query) if object.respond_to?(:append_cube_query)
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,18 +36,26 @@ 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
- options_keys = context_node.ast_node.arguments.detect{|x| x.name=='options'}.value.arguments.map{|x|
51
- x.name.underscore.to_sym
52
- }
49
+ if opt_keys_args = context_node.ast_node.arguments.detect{|x| x.name=='options'}.value.try(:arguments)
50
+ options_keys = opt_keys_args.map{|x|
51
+ x.name.underscore.to_sym
52
+ }
53
+ elsif opt_keys_args_opt_name = context_node.ast_node.arguments.detect{|x| x.name=='options'}.value.try(:name)
54
+ options_keys = context_node.query.variables[opt_keys_args_opt_name].arguments.argument_values.map{|x, y|
55
+ x.underscore.to_sym
56
+ }
57
+ end
58
+
53
59
  arguments['options'] = Hash[
54
60
  options_keys.collect{|key|
55
61
  raise "Unmatched key #{key}" unless options[key]
@@ -61,10 +67,20 @@ module Activecube
61
67
  arguments
62
68
  end
63
69
 
64
- def union?
70
+ def union? context_node
65
71
  context_node.return_type.kind_of? GraphQL::UnionType
66
72
  end
67
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
+
68
84
  def append_query query
69
85
  if parent
70
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.22"
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.22
4
+ version: 0.1.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleksey Studnev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-24 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
@@ -90,10 +90,6 @@ extensions: []
90
90
  extra_rdoc_files: []
91
91
  files:
92
92
  - ".gitignore"
93
- - ".idea/activecube-graphql.iml"
94
- - ".idea/misc.xml"
95
- - ".idea/modules.xml"
96
- - ".idea/workspace.xml"
97
93
  - ".rspec"
98
94
  - ".travis.yml"
99
95
  - CODE_OF_CONDUCT.md
@@ -114,7 +110,7 @@ homepage: https://github.com/bitquery/activecube-graphql
114
110
  licenses:
115
111
  - MIT
116
112
  metadata: {}
117
- post_install_message:
113
+ post_install_message:
118
114
  rdoc_options: []
119
115
  require_paths:
120
116
  - lib
@@ -129,8 +125,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
125
  - !ruby/object:Gem::Version
130
126
  version: '0'
131
127
  requirements: []
132
- rubygems_version: 3.0.4
133
- signing_key:
128
+ rubygems_version: 3.0.3
129
+ signing_key:
134
130
  specification_version: 4
135
131
  summary: Multi-Dimensional Queries using GraphQL
136
132
  test_files: []
@@ -1,61 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="RUBY_MODULE" version="4">
3
- <component name="ModuleRunConfigurationManager">
4
- <shared />
5
- </component>
6
- <component name="NewModuleRootManager">
7
- <content url="file://$MODULE_DIR$">
8
- <sourceFolder url="file://$MODULE_DIR$/features" isTestSource="true" />
9
- <sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
10
- <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
11
- </content>
12
- <orderEntry type="jdk" jdkName="RVM: ruby-2.6.3" jdkType="RUBY_SDK" />
13
- <orderEntry type="sourceFolder" forTests="false" />
14
- <orderEntry type="library" scope="PROVIDED" name="activecube (v0.1.35, RVM: ruby-2.6.3) [gem]" level="application" />
15
- <orderEntry type="library" scope="PROVIDED" name="activemodel (v6.1.4, RVM: ruby-2.6.3) [gem]" level="application" />
16
- <orderEntry type="library" scope="PROVIDED" name="activerecord (v6.1.4, RVM: ruby-2.6.3) [gem]" level="application" />
17
- <orderEntry type="library" scope="PROVIDED" name="activesupport (v6.1.4, RVM: ruby-2.6.3) [gem]" level="application" />
18
- <orderEntry type="library" scope="PROVIDED" name="bundler (v1.17.3, RVM: ruby-2.6.3) [gem]" level="application" />
19
- <orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.1.9, RVM: ruby-2.6.3) [gem]" level="application" />
20
- <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.3, RVM: ruby-2.6.3) [gem]" level="application" />
21
- <orderEntry type="library" scope="PROVIDED" name="graphql (v1.12.19, RVM: ruby-2.6.3) [gem]" level="application" />
22
- <orderEntry type="library" scope="PROVIDED" name="i18n (v1.8.11, RVM: ruby-2.6.3) [gem]" level="application" />
23
- <orderEntry type="library" scope="PROVIDED" name="minitest (v5.14.4, RVM: ruby-2.6.3) [gem]" level="application" />
24
- <orderEntry type="library" scope="PROVIDED" name="rake (v13.0.1, RVM: ruby-2.6.3) [gem]" level="application" />
25
- <orderEntry type="library" scope="PROVIDED" name="rspec (v3.9.0, RVM: ruby-2.6.3) [gem]" level="application" />
26
- <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.9.2, RVM: ruby-2.6.3) [gem]" level="application" />
27
- <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.9.2, RVM: ruby-2.6.3) [gem]" level="application" />
28
- <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.9.1, RVM: ruby-2.6.3) [gem]" level="application" />
29
- <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.9.3, RVM: ruby-2.6.3) [gem]" level="application" />
30
- <orderEntry type="library" scope="PROVIDED" name="tzinfo (v2.0.4, RVM: ruby-2.6.3) [gem]" level="application" />
31
- <orderEntry type="library" scope="PROVIDED" name="zeitwerk (v2.5.1, RVM: ruby-2.6.3) [gem]" level="application" />
32
- </component>
33
- <component name="RakeTasksCache">
34
- <option name="myRootTask">
35
- <RakeTaskImpl id="rake">
36
- <subtasks>
37
- <RakeTaskImpl description="Build activecube-graphql-0.1.19.gem into the pkg directory" fullCommand="build" id="build" />
38
- <RakeTaskImpl description="Remove any temporary products" fullCommand="clean" id="clean" />
39
- <RakeTaskImpl description="Remove any generated files" fullCommand="clobber" id="clobber" />
40
- <RakeTaskImpl description="Build and install activecube-graphql-0.1.19.gem into system gems" fullCommand="install" id="install" />
41
- <RakeTaskImpl id="install">
42
- <subtasks>
43
- <RakeTaskImpl description="Build and install activecube-graphql-0.1.19.gem into system gems without network access" fullCommand="install:local" id="local" />
44
- </subtasks>
45
- </RakeTaskImpl>
46
- <RakeTaskImpl description="Create tag v0.1.19 and build and push activecube-graphql-0.1.19.gem to rubygems.org" fullCommand="release[remote]" id="release[remote]" />
47
- <RakeTaskImpl description="Run RSpec code examples" fullCommand="spec" id="spec" />
48
- <RakeTaskImpl description="" fullCommand="default" id="default" />
49
- <RakeTaskImpl description="" fullCommand="release" id="release" />
50
- <RakeTaskImpl id="release">
51
- <subtasks>
52
- <RakeTaskImpl description="" fullCommand="release:guard_clean" id="guard_clean" />
53
- <RakeTaskImpl description="" fullCommand="release:rubygem_push" id="rubygem_push" />
54
- <RakeTaskImpl description="" fullCommand="release:source_control_push" id="source_control_push" />
55
- </subtasks>
56
- </RakeTaskImpl>
57
- </subtasks>
58
- </RakeTaskImpl>
59
- </option>
60
- </component>
61
- </module>
data/.idea/misc.xml DELETED
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="JavaScriptSettings">
4
- <option name="languageLevel" value="ES6" />
5
- </component>
6
- <component name="ProjectRootManager" version="2" project-jdk-name="ruby-2.3.3-p222" project-jdk-type="RUBY_SDK" />
7
- </project>
data/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/activecube-graphql.iml" filepath="$PROJECT_DIR$/.idea/activecube-graphql.iml" />
6
- </modules>
7
- </component>
8
- </project>
data/.idea/workspace.xml DELETED
@@ -1,26 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectId" id="1YAAllwtnwKyBVlMjptPbbPRXH8" />
4
- <component name="ProjectViewState">
5
- <option name="hideEmptyMiddlePackages" value="true" />
6
- <option name="showLibraryContents" value="true" />
7
- <option name="showMembers" value="true" />
8
- </component>
9
- <component name="PropertiesComponent">
10
- <property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
11
- <property name="nodejs_npm_path_reset_for_default_project" value="true" />
12
- <property name="settings.editor.selected.configurable" value="preferences.lookFeel" />
13
- </component>
14
- <component name="RunDashboard">
15
- <option name="ruleStates">
16
- <list>
17
- <RuleState>
18
- <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
19
- </RuleState>
20
- <RuleState>
21
- <option name="name" value="StatusDashboardGroupingRule" />
22
- </RuleState>
23
- </list>
24
- </option>
25
- </component>
26
- </project>