activecube-graphql 0.1.22 → 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: 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>