class Activecube::Graphql::ParseTree::Element
Constants
- KEY_FIELD_PREFIX
- NULLABLE_OPERATORS
- TYPENAME
Attributes
arguments[R]
ast_node[R]
children[R]
context_node[R]
cube[R]
definition[R]
dimension[R]
field[R]
key[R]
metric[R]
name[R]
parent[R]
Public Class Methods
new(cube, context_node, parent = nil)
click to toggle source
# File lib/activecube/graphql/parse_tree.rb, line 13 def initialize cube, context_node, parent = nil @cube = cube @parent = parent @name = context_node.name @key = parent ? (parent.key ? "#{parent.key}.#{name}" : KEY_FIELD_PREFIX+name ) : nil @context_node = context_node @ast_node = context_node.ast_node @arguments = sort_node_arguments ast_node, context_node.arguments.to_h if parent @definition = context_node.definitions.first.name if parent.dimension @dimension = parent.dimension @field = (parent.field || dimension)[definition.to_sym] raise Activecube::InputArgumentError, "#{definition} not implemented for #{key} in cube #{cube.name}" unless @field elsif !parent.metric if !(@metric = (cube.metrics && cube.metrics[definition.to_sym])) && !(@dimension = (cube.dimensions && cube.dimensions[definition.to_sym])) raise Activecube::InputArgumentError, "Metric or dimension #{definition} for #{key} not defined for cube #{cube.name}" end end end @children = context_node.typed_children.values.map(&:values).flatten.uniq(&:name). select{|child| child.name!=TYPENAME || union? }. collect do |child| Element.new cube, child, self end end
Public Instance Methods
append_query(query)
click to toggle source
# File lib/activecube/graphql/parse_tree.rb, line 68 def append_query query if parent if metric query = query.measure({key => apply_args(metric)}) elsif dimension if children.empty? query = query.slice({key => apply_args(field || dimension)}) elsif !arguments.empty? query = apply_args query end end else query = apply_args query, ( arguments && arguments.except('options')) query = apply_args query, ( arguments && arguments['options'] ) end children.each do |child| query = child.append_query query end query end
sort_node_arguments(ast_node, arguments)
click to toggle source
# File lib/activecube/graphql/parse_tree.rb, line 48 def sort_node_arguments ast_node, arguments if (options = arguments['options']).kind_of?(Hash) options_keys = context_node.ast_node.arguments.detect{|x| x.name=='options'}.value.arguments.map{|x| x.name.underscore.to_sym } arguments['options'] = Hash[ options_keys.collect{|key| raise "Unmatched key #{key}" unless options[key] [key, options[key]] } ] end arguments end
union?()
click to toggle source
# File lib/activecube/graphql/parse_tree.rb, line 64 def union? context_node.return_type.kind_of? GraphQL::UnionType end
Private Instance Methods
applicable_operator?(operator, arg)
click to toggle source
# File lib/activecube/graphql/parse_tree.rb, line 140 def applicable_operator? operator, arg !arg.nil? || NULLABLE_OPERATORS.include?(operator) end
apply_args(element, args = self.arguments)
click to toggle source
# File lib/activecube/graphql/parse_tree.rb, line 95 def apply_args element, args = self.arguments args && args.each_pair do |key, value| k = key.to_sym has_selectors = element.respond_to?(:selectors) if has_selectors && k==:any element = apply_or_selector element, value elsif has_selectors && (selector = cube.selectors[k]) if value.kind_of? Hash element = apply_selector element, k, value elsif value.kind_of? Array element = apply_to_array(element, k, selector, value) elsif !value.nil? element = element.when( selector.eq(value) ) end elsif element.respond_to? k element = element.send(k, *converted_field_array(k, value)) else raise Activecube::InputArgumentError, "Field #{k} is not implemented for #{element}" end end element end
apply_or_selector(element, value)
click to toggle source
# File lib/activecube/graphql/parse_tree.rb, line 144 def apply_or_selector element, value selectors = value.collect{|v| make_selector v }.compact element.when( Activecube::Query::Selector.or(selectors) ) end
apply_selector(element, k, hash)
click to toggle source
# File lib/activecube/graphql/parse_tree.rb, line 131 def apply_selector element, k, hash hash.each_pair do |operator, arg| selector = cube.selectors[k] raise Activecube::InputArgumentError, "#{selector} does not handle method '#{operator}' for #{element} '#{k}'" unless selector.respond_to?(operator) element = element.when( selector.send(operator, arg) ) if applicable_operator?(operator, arg) end element end
apply_to_array(element, k, selector, value)
click to toggle source
# File lib/activecube/graphql/parse_tree.rb, line 167 def apply_to_array(element, k, selector, value) if !value.detect { |e| !e.kind_of? Hash } value.each { |v| element = apply_selector element, k, v } else element = element.when(selector.in(value)) end element end
converted_field_array(method, values)
click to toggle source
# File lib/activecube/graphql/parse_tree.rb, line 120 def converted_field_array method, values case method when :desc,:asc values.collect{|v| KEY_FIELD_PREFIX + v} when :limit_by values.merge({each: KEY_FIELD_PREFIX + values[:each]}) else values end end
make_selector(hash)
click to toggle source
# File lib/activecube/graphql/parse_tree.rb, line 149 def make_selector hash raise Activecube::InputArgumentError, "Hash expected for selector, #{v} found instead" unless hash.kind_of?(Hash) selectors = hash.to_a.collect{|attr, expressions| k = attr.to_s.camelize(:lower).to_sym (expressions.kind_of?(Array) ? expressions : [expressions]).collect{|expression| expression.to_a.collect{|c| operator, arg = c selector = cube.selectors[k] raise Activecube::InputArgumentError, "Selector not found for '#{k}'" unless selector raise Activecube::InputArgumentError, "#{selector} does not handle method '#{operator}' '#{k}'" unless selector.respond_to?(operator) selector.send(operator, arg) unless arg.nil? selector } } }.flatten Activecube::Query::Selector.and(selectors) end